diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,194 +1,198 @@ .*/Makefile .*/Makefile\.in .*/\.deps .*/\.libs .*/.*\.l[ao] .*/.*\.so\.* .*/.*\.o .*~ .*/done-all-links lib/AriadneDefaults.rpo (DIPSY|src)/.*\.(run|tex|out|log|rpo|spc|top|dump|dot|aux|pdf|ps|png|svg|hepmc|dat|aida|rz|eps|root|tuple|gp|exe) src/done-all-links autom4te.cache aclocal.m4 libtool Makefile Makefile.in config.log config.status configure Config/config.h Config/config.h.in Config/config.sub Config/depcomp Config/install-sh Config/missing Config/stamp-h. Config/config.guess include/done-all-links include/Ariadne DIPSY/NuclearDistribution-1.C DIPSY/NuclearDistribution.C DIPSY/plots FTuneLEP/plots src/plots src/.*\.prof src/3jet.lhe.gz src/MadGraph_DIS src/mgdis.in src/runThePEG DIPSY/runThePEG lib/Ariadne5Defaults.rpo DIPSY/fsswing.txt DIPSY/rphi.pl DIPSY1991 DIPSY/mcnetRivetbin DIPSY/pythia8 DIPSY/exps DIPSY/temp.* DIPSY/95 DIPSY/.*\.yoda src/.*\.yoda DIPSY/.*\.info DIPSY/.*\.plot DIPSY/bugtest.in DIPSY/PPTune/.*\.prof DIPSY/PPTune/.*\.weights DIPSY/PPTune/.*\.prold DIPSY/PPTune/.*\.prout DIPSY/PPTune/.*\.prin src/.*\.prout src/.*\.prin DIPSY/PPTune/plots2 # added by aHg on Tue Oct 8 16:20:34 2013 syntax: glob DIPSY/TestRemnants.in # added by aHg on Tue Oct 8 16:21:11 2013 syntax: glob src/MTuneLEP.prof/ipol/profipol_quadratic_a3d80e6417a4670a4a51a4dbc59e222b.pkl # added by aHg on Tue Nov 5 17:09:03 2013 syntax: glob src/used_params # added by aHg on Tue Nov 26 09:38:47 2013 syntax: glob DIPSY/dummy.pl # added by aHg on Fri Feb 7 15:50:55 2014 syntax: glob DIPSY/PPTune.in # added by aHg on Fri Feb 7 15:51:31 2014 syntax: glob DIPSY/PPTune/PPTune.in # added by aHg on Fri Feb 7 15:51:42 2014 syntax: glob DIPSY/PPTune/runThePEG # added by aHg on Thu Feb 13 15:30:42 2014 syntax: glob DIPSY/PPTune/plots # added by aHg on Thu Feb 13 15:31:13 2014 syntax: glob lib/DIPSYDefaults.rpo # added by aHg on Thu Feb 13 15:31:23 2014 syntax: glob DIPSY/PPTune/refs/refs # added by aHg on Mon Mar 24 12:09:16 2014 syntax: glob DIPSY/PPTune/dummy.in # added by aHg on Mon Mar 24 12:09:57 2014 syntax: glob DIPSY/RHICAuAuCBorig.in # added by aHg on Mon Mar 24 12:10:24 2014 syntax: glob DIPSY/RHICAuAuCB.in # added by aHg on Mon Mar 24 12:10:37 2014 syntax: glob DIPSY/PPTune/MC_MYFB.cc # added by aHg on Tue May 20 12:01:05 2014 syntax: glob DIPSY/testrebind.in # added by aHg on Tue Jun 24 10:20:44 2014 syntax: glob DIPSY/PPTune/ratio.txt # added by aHg on Tue Jun 24 10:21:04 2014 syntax: glob src/ratio.txt # added by aHg on Fri Jun 27 14:15:27 2014 syntax: glob DIPSY/PPTune/test.in # added by aHg on Fri Aug 29 15:09:08 2014 syntax: glob DIPSY/CBDebug.in # added by aHg on Tue Dec 2 11:03:02 2014 syntax: glob DIPSY/#glauber.txt# # added by aHg on Tue Oct 13 09:11:34 2015 syntax: glob src/FTuneLEP/Ariadne5Defaults.in # added by aHg on Tue Oct 13 09:11:49 2015 syntax: glob src/FTuneLEP/Ariadne5Remove.in # added by aHg on Tue Oct 13 09:11:58 2015 syntax: glob src/FTuneLEP/TestAriadne5.in # added by aHg on Tue Oct 13 09:12:04 2015 syntax: glob src/FTuneLEP/TestAriadne5DIS.in # added by aHg on Tue Oct 13 09:12:09 2015 syntax: glob src/FTuneLEP/TestAriadne5Z0.in # added by aHg on Tue Oct 13 09:15:48 2015 syntax: glob src/FTuneLEP/runThePEG # added by aHg on Tue Dec 1 22:51:13 2015 syntax: glob include/C:\\nppdf32Log\\debuglog.txt # added by aHg on Fri Feb 12 16:24:47 2016 syntax: glob src/FTuneLEP/h200.lhe # added by aHg on Fri Feb 12 16:25:02 2016 syntax: glob src/FTuneLEP/h400.lhe src/FTuneLEP/h50.lhe src/FTuneLEP/h800.lhe src/FTuneLEP/z1600.lhe src/FTuneLEP/z200.lhe src/FTuneLEP/z400.lhe src/FTuneLEP/z50.lhe src/FTuneLEP/z800.lhe # added by aHg on Fri Apr 8 14:54:25 2016 syntax: glob src/FTuneLEP/h100.lhe # added by aHg on Fri Apr 8 14:54:39 2016 syntax: glob src/FTuneLEP/z100.lhe + +# added by aHg on Thu Sep 27 13:33:42 2018 +syntax: glob +src/FTuneLEP/rivet-plots diff --git a/Cascade/AriadneHandler.cc b/Cascade/AriadneHandler.cc --- a/Cascade/AriadneHandler.cc +++ b/Cascade/AriadneHandler.cc @@ -1,822 +1,822 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the AriadneHandler class. // #include "AriadneHandler.h" #include "ConsistencyChecker.h" #include "QCDDipoleFinder.h" #include "EMDipoleFinder.h" #include "ReweightBase.h" #include "DipoleState.h" #include "EmitterBase.h" #include "BornCheckerBase.h" #include "ScaleSetter.h" #include "DISFinder.h" #include "ResonanceFinder.h" #include "Ariadne/Cascade/Models/RemnantModel.h" #include "Ariadne/Cascade/Models/ColourResonanceModel.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/EventRecord/Collision.h" #include "ThePEG/EventRecord/SubProcess.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Handlers/EventHandler.h" #include "ThePEG/Handlers/Hint.h" #include "ThePEG/Handlers/XComb.h" #include "ThePEG/Utilities/UtilityBase.h" #include "ThePEG/Utilities/DescriptionList.h" #include "ThePEG/Utilities/Throw.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/Utilities/EnumIO.h" #include "ThePEG/Utilities/Current.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/Utilities/DebugItem.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Utilities/DescribeClass.h" #include "Models/FSGluonEmission.h" #include "Models/FSQQEmission.h" #include "Models/DipoleSwing.h" #include "ThePEG/Analysis/FactoryBase.h" #ifndef LWH_AIAnalysisFactory_H #ifndef LWH #define LWH ThePEGLWH #endif #include "ThePEG/Analysis/LWH/AnalysisFactory.h" #endif using namespace Ariadne5; AriadneHandler::AriadneHandler() : theRunningCoupling(simpleRunning), theAlpha0(0.2), theLambdaQCD(0.22*GeV), scaleFactor(1.0), thePTCut(0.6*GeV), theAlphaEM0(1.0/137.0), thePTCutEM(0.6*GeV), theNCol(8), theNFlav(5), thePhotonEmissions(false), theSoftMu(0.6*GeV), theSoftAlpha(1.0), theHardAlpha(-1.0), theBeta(2.0), theMaxEmissions(0), suspendConsistencyChecks(false), thePurgeStrategy(neverpurge), thePurgeFactor(0.0) {} AriadneHandler::~AriadneHandler() {} IBPtr AriadneHandler::clone() const { return new_ptr(*this); } IBPtr AriadneHandler::fullclone() const { return new_ptr(*this); } bool AriadneHandler::preInitialize() const { if ( CascadeHandler::preInitialize() ) return true; return runningCoupling() == internalRunning && !internalAlphaS(); } -void AriadneHandler::doinit() throw(InitException) { +void AriadneHandler::doinit() { CascadeHandler::doinit(); if ( runningCoupling() != internalRunning || internalAlphaS() ) return; theInternalAlphaS = dynamic_ptr_cast::pointer> (generator()->preinitCreate("ThePEG::O1AlphaS", fullName() + "/AlphaS", "O1AlphaS.so")); ostringstream os; os << ounit(lambdaQCD(), GeV); generator()->preinitInterface(theInternalAlphaS, "LambdaQCD", "set", os.str()); generator()->preinitInterface(theInternalAlphaS, "LambdaFlav", "set", "5"); theInternalAlphaS->update(); // Remove duplicate emitters. vector cleaned; set cleanset; for ( int i = 0, N = emitters().size(); i < N; ++i ) { const ClassDescriptionBase * cd = DescriptionList::find(typeid(*emitters()[i])); if ( cleanset.find(cd) != cleanset.end() ) continue; cleaned.push_back(emitters()[i]); cleanset.insert(cd); } theEmitters.swap(cleaned); } void AriadneHandler::doinitrun() { static DebugItem histem("Ariadne5::HistEm", 6); CascadeHandler::doinitrun(); theFlavourThresholds.clear(); vector thrsh; switch ( runningCoupling() ) { case noRunning: return; case simpleRunning: case externalRunning: thrsh = SM().alphaSPtr()->flavourThresholds(); break; case internalRunning: thrsh = internalAlphaS()->flavourThresholds(); } for ( int i = 0, N = thrsh.size(); i < N; ++i ) thrsh[i] /= scaleFactor; theFlavourThresholds.insert(thrsh.begin(), thrsh.end()); if ( histem ) { generator()->histogramFactory()->initrun(); generator()->histogramFactory()->registerClient(this); generator()->histogramFactory()->mkdir("/Ariadne5Debug"); histall = generator()->histogramFactory()->createHistogram1D ("/Ariadne5Debug/All", 100, -1.0, 9.0); histswing = generator()->histogramFactory()->createHistogram1D ("/Ariadne5Debug/Swings", 100, -1.0, 9.0); histglue = generator()->histogramFactory()->createHistogram1D ("/Ariadne5Debug/Glue", 100, -1.0, 9.0); histqq = generator()->histogramFactory()->createHistogram1D ("/Ariadne5Debug/QQ", 100, -1.0, 9.0); histlam = generator()->histogramFactory()->createHistogram1D ("/Ariadne5Debug/Lambda", 100, -1.0, 9.0); } } void AriadneHandler::cascade() { static DebugItem histem("Ariadne5::HistEm", 6); static DebugItem tupleswing("Ariadne5::SwingTuple", 6); static ofstream swingtuple; if ( tupleswing ) { static bool isopen = false; if ( !isopen ) { string filename = CurrentGenerator::current().filename() + "-swing.tuple"; swingtuple.open(filename.c_str()); isopen = true; } } Current current(this); DipoleStatePtr state; tSubProPtr sub; tPVector final; Energy rhomax = ZERO; // Energy rhomin = pTCut(); Energy rhomin = ZERO; bool perf = false; int emnbr = 0; // Check if the state has already been generated in reweightCKKW if ( theCKKWMap.count(lastXCombPtr()) ){ CKKWState ckkw = theCKKWMap[lastXCombPtr()]; sub = subProcess(); state = ckkw.history->state(); checkState(*state); rhomax = startingScale(*state); while ( emnbr == 0 && ( rhomax = state->select(rhomin, rhomax) ) > rhomin ) { SaveDipoleState backup(state); if ( state->perform() ) { if ( !ckkw.maxMult && checkTreeState(*state) && passCuts(state) ) { theCKKWMap.clear(); throw Veto(); } perf = true; emnbr++; } else { state = backup.revert(); state->selected()->dipole->touch(); } } } else { tCollPtr coll = eventHandler()->currentCollision(); state = new_ptr(DipoleState(coll->incoming())); sub = coll->primarySubProcess(); if ( sub->decayed() ) sub = tSubProPtr(); // Decide whether we are cascadeing a whole sub-process or if we // only need to deal with final-state shower. if ( ( hint().tagged() || !sub ) && !tagged().empty() ) { final = tagged(); } else if ( sub ) { state->setup(*sub); } else return; if ( !final.empty() ) { state->setup(set(final.begin(), final.end())); } checkState(*state); if ( !state->checkIntegrity() ) Throw() << "Ariadne failed to setup dipole system. This is a serious error," << "Please inform the author." << Exception::runerror; rhomax = startingScale(*state); } theCKKWMap.clear(); if ( tupleswing ) { swingtuple << "# " << setw(4) << CurrentGenerator::current().currentEventNumber() << setw(8) << "rho" << setw(14) << "lam/dip" << setw(14) << "lambda" << setw(6) << "cross" << setw(6) << "below" << setw(14) << "folding" << setw(6) << "geno" << setw(6) << "emno" << endl; pair lam = state->lambdaMeasure(sqr(pTCut())); int cross = state->crossings(); swingtuple << setw(14) << log10(rhomax/GeV) << setw(14) << lam.first/lam.second << setw(14) << lam.first << setw(6) << cross << setw(6) << state->gluonsBelow() << setw(14) << state->folding() << endl; } if ( purgeStrategy() == onlybefore || purgeStrategy() > neverpurge ) state->purgeGluons(pTCut()*purgeFactor()); if ( tupleswing ) { pair lam = state->lambdaMeasure(sqr(pTCut())); int cross = state->crossings(); swingtuple << setw(14) << log10(rhomax/GeV) << setw(14) << lam.first/lam.second << setw(14) << lam.first << setw(6) << cross << setw(6) << state->gluonsBelow() << setw(14) << state->folding() << endl; } while ( ( rhomax = state->select(rhomin, rhomax) ) > rhomin && ( maxEmissions() == 0 || emnbr < maxEmissions() ) ) { SaveDipoleState backup(state); if ( state->perform() ) { perf = true; emnbr++; if ( tupleswing ) { double lrho = log10(state->selected()->rho/GeV); pair lam = state->lambdaMeasure(sqr(pTCut())); int cross = state->crossings(); swingtuple << setw(14) << lrho << setw(14) << lam.first/lam.second << setw(14) << lam.first << setw(6) << cross << setw(6) << state->gluonsBelow() << setw(14) << state->folding() << setw(6) << state->selected()->geno << setw(6) << state->selected()->emno; if ( DipoleSwing * em = dynamic_cast((Emission*)(state->selected())) ) { swingtuple << "s" << setw(6) << state->index(em->dipoles.first) << setw(6) << state->index(em->dipoles.second); } else if ( dynamic_cast((Emission*)(state->selected())) ) swingtuple << "g" << setw(6)<< state->index(state->selected()->dipole); else if ( dynamic_cast((Emission*)(state->selected())) ) swingtuple << "q" << setw(6) << state->index(state->selected()->dipole); swingtuple << endl; } if ( histem ) { double w = 1.0/double(state->activeDipoles().size()); double lrho = log10(state->selected()->rho/GeV); histall->fill(lrho, w); histlam->fill(lrho, state->lambdaMeasure().first); if ( dynamic_cast((Emission*)(state->selected())) ) histswing->fill(lrho, w); else if ( dynamic_cast((Emission*)(state->selected())) ) histglue->fill(lrho, w); else if ( dynamic_cast((Emission*)(state->selected())) ) histqq->fill(lrho, w); else state->selected()->debug(); } if ( purgeStrategy() == everystep ) state->purgeGluons(pTCut()*purgeFactor()); } else { state = backup.revert(); state->selected()->dipole->touch(); } if ( !state->checkIntegrity() ) { throw IntegretyException() << "AriadneHandler::cascade " << "The dipole state is not self consistent." << Exception::eventerror; } } if ( perf && ( purgeStrategy() == onlyafter || purgeStrategy() == beforeandafter ) ) state->purgeGluons(pTCut()*purgeFactor()); if ( tupleswing ) { pair lam = state->lambdaMeasure(sqr(pTCut())); int cross = state->crossings(); swingtuple << setw(14) << log10(pTCut()/GeV) << setw(14) << lam.first/lam.second << setw(14) << lam.first << setw(6) << cross << setw(6) << state->gluonsBelow() << setw(14) << state->folding() << endl; } if ( final.empty() ) { if ( perf ) state->fill(*newStep()); sub->decayed(true); } else { if ( perf ) state->fill(*newStep()); } } double AriadneHandler::reweightCKKW(int minMult, int maxMult) { if(minMult == maxMult){ return 1.0; } CKKWState ckkw; DipoleStatePtr state = new_ptr(DipoleState()); tXCPtr lastXC = lastXCombPtr(); int outgoing = lastXC->subProcess()->outgoing().size(); if ( outgoing < minMult || outgoing > maxMult ) { throw CKKWMultiplicityException() << "Ariadne5::CascadeHandler::reweightCKKW " << "Number of outgoing particles out of range." << Exception::eventerror; } int steps = outgoing - minMult; ckkw.maxMult = (outgoing == maxMult); state->setup(*(lastXC->subProcess())); checkState(*state); if ( !state->checkIntegrity() ) Throw() << "Ariadne failed to setup dipole system. This is a serious error," << "Please inform the author." << Exception::runerror; ckkw.history = HistoryPtr(new History(steps, state)); if ( !ckkw.history->select() ) return 0.0; double w = ckkw.history->weight(lastXC->lastAlphaS(), lastXC->lastScale()); if ( w > 0.0 ) theCKKWMap[lastXC] = ckkw; return w; } bool AriadneHandler::passCuts(tcDipoleStatePtr state) { /* *** ATTENTION *** tCutsPtr cuts = lastCutsPtr(); Lorentz5Momentum ph = state->hardFS().momentum(); cuts->initSubProcess(ph.mass2(), ph.rapidity()); tcPDVector pdata; vector< LorentzMomentum > p; typedef HardSubSys::PartonSet PartonSet; const PartonSet & active = state->hardSubSys().coloured(); const PartonSet & produced = state->hardSubSys().produced(); for(PartonSet::const_iterator it = active.begin(); it != active.end(); it++){ pdata.push_back((*it)->dataPtr()); p.push_back((*it)->momentum()); } for(PartonSet::const_iterator it = produced.begin(); it != produced.end(); it++){ pdata.push_back((*it)->dataPtr()); p.push_back((*it)->momentum()); } LorentzRotation R(0.0, 0.0, - ph.z()/ph.e()); Utilities::transform(p, R); return cuts->passCuts(pdata, p, state->particles().first->dataPtr(), state->particles().second->dataPtr()); */ return false; } double AriadneHandler::alphaS(Energy2 scale) const { scale *= scaleFactor; int Nf = SM().Nf(scale); switch ( runningCoupling() ) { case noRunning: return alpha0(); case simpleRunning: return 12.0*Constants::pi/ ((33.0 - 2.0*min(int(SM().Nf(scale)),5))*log(scale/sqr(lambdaQCD()))); case internalRunning: return internalAlphaS()->value(scale, SM()); case externalRunning: return SM().alphaS(scale); } return ZERO*Nf; } Energy AriadneHandler::checkBornState(const DipoleState & ds) const { Energy scale = ZERO; for ( int i = 0, N = theBornCheckers.size(); i < N; ++i ) { Energy mu = theBornCheckers[i]->check(ds); if ( mu > ZERO ) return mu; if ( scale == ZERO ) scale = mu; } if ( scale == ZERO ) Throw() << "Could not reconstruct the given event in the CKKW-L algorithm. " << *(eventHandler()->currentEvent()) << Exception::runerror; return scale; } bool AriadneHandler::checkTreeState(const DipoleState & ds) const { for ( int i = 0, N = theBornCheckers.size(); i < N; ++i ) if ( theBornCheckers[i]->checkTree(ds) ) return true; return false; } vector AriadneHandler::findQCDDipoles(DipoleState & state) const { return theQCDFinder->findDipoles(state); } vector AriadneHandler::findEMDipoles(DipoleState & state) const { return theEMFinder? theEMFinder->findDipoles(state): vector(); } Energy AriadneHandler::startingScale(const DipoleState & state) const { return theScaleSetter->scale(state); } bool AriadneHandler::checkState(DipoleState & state, tcEmPtr e) { if ( !consistency ) return true; if ( !e ) suspendConsistencyChecks = false; else if ( suspendConsistencyChecks ) return true; if ( consistency->check(state, e) ) return true; if ( !e ) suspendConsistencyChecks = true; return false; } pair AriadneHandler::findDISLeptons(SubProcess & sub, DipoleState & state) const { return theDISFinder? theDISFinder->findDISLeptons(sub, state): pair(); } pair AriadneHandler::findDISQuarks(pair leptons, SubProcess & sub, DipoleState & state) const { return theDISFinder? theDISFinder->findDISQuarks(leptons, sub, state): pair(); } tPVector AriadneHandler::resonances(SubProcess & sub) const { return theResonanceFinder->resonances(sub); } void AriadneHandler::persistentOutput(PersistentOStream & os) const { os << oenum(theRunningCoupling) << theAlpha0 << ounit(theLambdaQCD, GeV) << theInternalAlphaS << scaleFactor << theFlavourThresholds.size() << ounit(thePTCut, GeV) << theAlphaEM0 << ounit(thePTCutEM, GeV) << theNCol << theNFlav << thePhotonEmissions << ounit(theSoftMu, GeV) << theSoftAlpha << theHardAlpha << theBeta << theReweighters << theMaxEmissions << theEmitters << theBornCheckers << theScaleSetter << theDISFinder << theResonanceFinder << theQCDFinder << theEMFinder << theColourResonanceModel << theRemnantModel << consistency << suspendConsistencyChecks << oenum(thePurgeStrategy) << thePurgeFactor; for ( set::const_iterator it = theFlavourThresholds.begin(); it != theFlavourThresholds.end(); ++it ) os << ounit(*it, GeV2); } void AriadneHandler::persistentInput(PersistentIStream & is, int) { int size = 0; is >> ienum(theRunningCoupling) >> theAlpha0 >> iunit(theLambdaQCD, GeV) >> theInternalAlphaS >> scaleFactor >> size >> iunit(thePTCut, GeV) >> theAlphaEM0 >> iunit(thePTCutEM, GeV) >> theNCol >> theNFlav >> thePhotonEmissions >> iunit(theSoftMu, GeV) >> theSoftAlpha >> theHardAlpha >> theBeta >> theReweighters >> theMaxEmissions >> theEmitters >> theBornCheckers >> theScaleSetter >> theDISFinder >> theResonanceFinder >> theQCDFinder >> theEMFinder >> theColourResonanceModel >> theRemnantModel >> consistency >> suspendConsistencyChecks >> ienum(thePurgeStrategy) >> thePurgeFactor; theFlavourThresholds.clear(); Energy2 t = ZERO; for ( int i = 0; i < size; ++i ) { is >> iunit(t, GeV2); theFlavourThresholds.insert(t); } } DescribeClass describeAriadne5("Ariadne5::AriadneHandler", "libAriadne5.so"); Energy AriadneHandler::minPTCut() const { return ( runningCoupling() == simpleRunning || ( runningCoupling() == internalRunning && !theInternalAlphaS ) )? lambdaQCD()/sqrt(scaleFactor): 0.0*GeV; } Energy AriadneHandler::maxLambdaQCD() const { return ( runningCoupling() == simpleRunning || ( runningCoupling() == internalRunning && !theInternalAlphaS ) )? pTCut()*sqrt(scaleFactor): Constants::MaxEnergy; } void AriadneHandler::Init() { static ClassDocumentation documentation ("The AriadneHandler class administers the Ariadne dipole " "cascade.", "Parton cascades performed by Ariadne\\cite{Lav05} according to the " "Dipole Cascade Model\\cite{Gustafson:1986db,Gustafson:1988rq," "Andersson:1989gp,Andersson:1990ki}.", "\\bibitem{Lav05}" "Nils Lavesson and Leif L\\\"onnblad, Preprint in preparation.\n" "\\bibitem{Gustafson:1986db}" "G\\\"osta Gustafson, Phys.~Lett.~{\\bf B175} (1986) 453.\n" "\\bibitem{Gustafson:1988rq}" "G\\\"osta Gustafson and Ulf Pettersson, " "Nucl.~Phys.~{\\bf B306} (1988) 746.\n" "\\bibitem{Andersson:1989gp}" "Bo Andersson, et al., Z.~Phys.~{\\bf C43} (1989) 625.\n" "\\bibitem{Andersson:1990ki}" "Bo Andersson, et al., Nucl.~Phys.~{\\bf B339} (1990) 393."); static Switch interfaceRunningCoupling ("RunningCoupling", "Strategy for handling \\f$\\alpha_S\\f$.", &AriadneHandler::theRunningCoupling, simpleRunning, true, false); static SwitchOption interfaceRunningCouplingSimpleRunning (interfaceRunningCoupling, "SimpleRunning", "Use a one loop running coupling with \\f$\\Lambda_{QCD}\\f$ given " "by LambdaQCD.", simpleRunning); static SwitchOption interfaceRunningCouplingConstant (interfaceRunningCoupling, "Constant", "Use a constant coupling given by Alpha0.", noRunning); static SwitchOption interfaceRunningCouplingExternalRunning (interfaceRunningCoupling, "ExternalRunning", "Use whatever coupling is specified by the current StandardModelBase " "object.", externalRunning); static SwitchOption interfaceRunningCouplingInternalRUnning (interfaceRunningCoupling, "InternalRunning", "Use the coupling specified by InternalAlphaS.", internalRunning); static Parameter interfaceAlpha0 ("Alpha0", "The constant \\f$\\alpha_S\\f$ to use if " "RunningCoupling is set to Constant.", &AriadneHandler::theAlpha0, 0.2, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfaceAlphaEM0 ("AlphaEM0", "The constant \\f$\\alpha_{EM}\\f$ to use. If zero, use whatever " "is specified in the current StandardModelBase object.", &AriadneHandler::theAlphaEM0, 1.0/137.0, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfaceLambdaQCD ("LambdaQCD", "The \\f$\\Lambda_{QCD}\\f$ to use in the one loop running " "\\f$\\alpha_S\\f$ if RunningCoupling " "is set to Running.", &AriadneHandler::theLambdaQCD, GeV, 0.22*GeV, 0.0*GeV, Constants::MaxEnergy, true, false, Interface::limited, 0, 0, 0, &AriadneHandler::maxLambdaQCD, 0); static Parameter interfaceScaleFactor ("ScaleFactor", "Scale factor used to multiply the emission scales in the argument of " "\\f$\alpha_S\\f$.", &AriadneHandler::scaleFactor, 1.0, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfacePTCut ("PTCut", "The cutoff in invariant transverse momentum for QCD emissions.", &AriadneHandler::thePTCut, GeV, 0.6*GeV, 0.0*GeV, 0*GeV, true, false, Interface::lowerlim, 0, 0, &AriadneHandler::minPTCut, 0, 0); static Parameter interfacePTCutEM ("PTCutEM", "The cutoff in invariant transverse momentum for QED emissions.", &AriadneHandler::thePTCutEM, GeV, 0.6*GeV, 0.0*GeV, 0*GeV, true, false, Interface::lowerlim); static Parameter interfaceDipoleColours ("DipoleColours", "The number of differently coloured dipoles possible. This should " "normally be 8, but may be varied to check the effects of colour " "reconnections.", &AriadneHandler::theNCol, 8, 3, 0, true, false, Interface::lowerlim); static Parameter interfaceNFlav ("NFlav", "The number of possible flavours in a \f$g\to q\bar{q}\f$ splitting.", &AriadneHandler::theNFlav, 5, 0, 8, true, false, Interface::lowerlim); static Switch interfacePhotonEmissions ("PhotonEmissions", "Switches photon emission in the cascade on and off.", &AriadneHandler::thePhotonEmissions, false, true, false); static SwitchOption interfacePhotonEmissionsOn (interfacePhotonEmissions, "On", "Switch photon emission on", true); static SwitchOption interfacePhotonEmissionsOff (interfacePhotonEmissions, "Off", "Switch photon emission off.", false); static Parameter interfaceSoftMu ("SoftMu", "The inverse extension of a hadron remnant used in the soft " "suppression mechanism. See also SoftAlphs and " "Beta", &AriadneHandler::theSoftMu, GeV, 0.6*GeV, 0.0*GeV, 0*GeV, true, false, Interface::lowerlim); static Parameter interfaceSoftAlpha ("SoftAlpha", "The dimension of the extension of a hadron remnant used in the " "soft-suppression mechanism. See also SoftMu " "and Beta.", &AriadneHandler::theSoftAlpha, 1.0, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfaceHardAlpha ("HardAlpha", "The dimension of the extension of a hard remnant used in the " "soft-suppression mechanism for radiation off a scattered quark in " "DIS at small \\f$Q^2\\f$. If set negative, the value of " "SoftAlpha will be used instead. See also " "Beta.", &AriadneHandler::theHardAlpha, -1.0, -1.0, 0, true, false, Interface::lowerlim); static Parameter interfaceBeta ("Beta", "The power in the suppression of radiation from extended dipoles. " "The original soft suppression model used a sharp cutoff in the " "transverse-momentum--rapidity space of an emitted gluon. This parameter " "is used to allow emissions with larger transverse momentum according to " "\\f$P(p_\\perp^2>p_{\\perp cut}^2=" "\\left(\\frac{p_{\\perp cut}^2}{p_\\perp^2}\\right)^\\beta\\f$. if " "negative, the sharp cutoff is retained.", &AriadneHandler::theBeta, 2.0, -1.0, 0, true, false, Interface::lowerlim); static RefVector interfaceReweighters ("Reweighters", "A vector of objects implementing reweightings of basic dipole " "emissions. Each dipole emission will be reweighted.", &AriadneHandler::theReweighters, -1, true, false, true, false, false); static Parameter interfaceMaxEmissions ("MaxEmissions", "This number specifies the maximum number of emissions from the " "cascade. If it is set to zero an unlimited number is allowed. " "This parameter should only be used for debugging purposes.", &AriadneHandler::theMaxEmissions, 0, 0, 0, true, false, Interface::lowerlim); static Reference interfaceInternalAlphaS ("InternalAlphaS", "An internal AlphaSBase object to be used if " "RunningCoupling is set to InternalRunning. " "If no such object is given, A O1AlphaS object will be created and " "assigned in the initialization with LambdaQCD " "used as lambda for five flavours.", &AriadneHandler::theInternalAlphaS, true, false, true, true, false); static RefVector interfaceEmitters ("Emitters", "The vector of EmittorBase objects responsible for generatong and " "performing emissions according to the Dipole Cascade Model and its " "extentions. For each dipole, all Emitters are tried in turn if to see " "if they are able to model emissions. Only one EmittorBase object of " "each SubClass will be used (earlier ones will override later ones " "in the vector).", &AriadneHandler::theEmitters, -1, true, false, true, false, false); static RefVector interfaceBornCheckers ("BornCheckers", " A vector of BornCheckerBase objects which are used in the CKKW-L " "algorithm to check if a reclustered dipole state corresponds to a " "reasonable Born-level state (the lowest jet-multiplicity state in a " "CKKW-L merging). At least one object must be assigned in order for " "the CKKW-L algorithm to work.", &AriadneHandler::theBornCheckers, -1, true, false, true, false, false); static Reference interfaceScaleSetter ("ScaleSetter", "The object responsible for choosing the starting scale of the " "Ariadne dipole shower.", &AriadneHandler::theScaleSetter, true, false, true, false, true); static Reference interfaceDISFinder ("DISFinder", "The object responsible for identifying DIS-like event.", &AriadneHandler::theDISFinder, true, false, true, true, false); static Reference interfaceResonanceFinder ("ResonanceFinder", "The object responsible for identifying DIS-like event.", &AriadneHandler::theResonanceFinder, true, false, true, false, false); static Reference interfaceQCDFinder ("QCDFinder", "The Object responsible for identifying QCD Diploles.", &AriadneHandler::theQCDFinder, true, false, true, false, false); static Reference interfaceEMFinder ("EMFinder", "The Object responsible for identifying electro-magnetic Diploles. " "If null, all electro-magnetic radiation will be switched off.", &AriadneHandler::theEMFinder, true, false, true, true, false); static Reference interfaceColourResonanceModel ("ColourResonanceModel", "The object responsible for radiating from decay products from " "coloured resonances.", &AriadneHandler::theColourResonanceModel, true, false, true, true, false); static Reference interfaceRemnantModel ("RemnantModel", "The object responsible for radiating from remnants.", &AriadneHandler::theRemnantModel, true, false, true, false, false); static Reference interfaceConsistencyChecker ("ConsistencyChecker", "The object responsible for checking the consistency of a DipoleState.", &AriadneHandler::consistency, true, false, true, true, false); static Switch interfacePurgeStrategy ("PurgeStrategy", "The strategy for purging gluons with transverse momentum less than a factor PurgeFactor times the cutoff.", &AriadneHandler::thePurgeStrategy, neverpurge, true, false); static SwitchOption interfacePurgeStrategyOnlyBefore (interfacePurgeStrategy, "OnlyBefore", "Gluons are only purged before the cascade.", onlybefore); static SwitchOption interfacePurgeStrategyOnlyAfter (interfacePurgeStrategy, "OnlyAfter", "Gluons are only purged after the cascade.", onlyafter); static SwitchOption interfacePurgeStrategyNever (interfacePurgeStrategy, "Never", "Gluon purging is switched off.", neverpurge); static SwitchOption interfacePurgeStrategyBeforeAndAfter (interfacePurgeStrategy, "BeforeAndAfter", "Gluons are purged before and after the cascade.", beforeandafter); static SwitchOption interfacePurgeStrategyEveryStep (interfacePurgeStrategy, "EveryStep", "Gluons are purged before (and after) each step of the cascade.", everystep); static Parameter interfacePurgeFactor ("PurgeFactor", "The factor used to determine how far below the cutoff a gluon may be before " "it is purged. If the transverse momentum of a gluon is less than this factor " "times the cutoff it will be purged. Cf. PurgeStrategy.", &AriadneHandler::thePurgeFactor, 0.0, 0.0, 0, true, false, Interface::lowerlim); interfacePTCut.rank(10); interfaceLambdaQCD.rank(9); interfaceNFlav.rank(8); interfaceSoftMu.rank(7); interfaceSoftAlpha.rank(6); interfaceHardAlpha.rank(5); interfaceBeta.rank(4); } diff --git a/Cascade/AriadneHandler.h b/Cascade/AriadneHandler.h --- a/Cascade/AriadneHandler.h +++ b/Cascade/AriadneHandler.h @@ -1,664 +1,664 @@ // -*- C++ -*- #ifndef Ariadne5_AriadneHandler_H #define Ariadne5_AriadneHandler_H // // This is the declaration of the AriadneHandler class. // #include "Ariadne/Config/Ariadne5.h" #include "ThePEG/Handlers/CascadeHandler.h" #include "ThePEG/StandardModel/AlphaSBase.h" #include "AriadneHandler.fh" #include "History.fh" #include "ReweightBase.fh" #include "DipoleState.fh" #include "EmitterBase.fh" #include "BornCheckerBase.fh" #include "ScaleSetter.fh" #include "DISFinder.fh" #include "QCDDipoleFinder.fh" #include "EMDipoleFinder.fh" #include "ResonanceFinder.fh" #include "History.h" #include "ConsistencyChecker.fh" #include "QCDDipole.fh" #include "EMDipole.fh" #include "Ariadne/Cascade/Models/RemnantModel.fh" #include "Ariadne/Cascade/Models/ColourResonanceModel.fh" #include "ThePEG/Analysis/FactoryBase.h" namespace Ariadne5 { using namespace ThePEG; /** * The AriadneHandler class inherits form the ThePEG::CascadeHandler * base class and implements the Dipole Cascade Model for partonic * cascades. * * @see \ref AriadneHandlerInterfaces "The interfaces" * defined for AriadneHandler. */ class AriadneHandler: public CascadeHandler { public: /** * Enum different options for running \f$\alpha_s\f$. */ enum RunningOption { externalRunning = -1, /**< Use the \f$\alpha_s\f$ specified in the current StandardModel object. */ noRunning = 0, /**< Use a fixed \f$\alpha_s\f$ specified by alpha0(). */ simpleRunning = 1, /**< Use simple leading order running with \f$\Lambda_{QCD}\f$ given by lambdaQCD() */ internalRunning = 2 /**< Use internal AlphaSBase object in theInternalAlphaS for the running. */ }; /** * Enumerate strategies for purging gluons with too small transverse momentum. */ enum PurgeStrategy { onlybefore = -1, /**< Only purge gluons before the cascade. */ onlyafter = -2, /**< Only purge gluons after the cascade. */ neverpurge = 0, /**< Never purge gluons. */ beforeandafter = 1, /**< Purge gluons before and after the cascade. */ everystep = 2 /**< Purge gluons every step. */ }; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ AriadneHandler(); /** * The destructor. */ virtual ~AriadneHandler(); //@} public: /** * The main function to be overwritten by sub-classes. It is called * by handle() after storing some information which is then * available through simple access functions. */ virtual void cascade(); /** * The AriadneHandler can be used inside the process generation to do * so-called CKKW reweighting of the hard sub-process. In this case * this function is called after information about the sub-process is * made available through the LastXCombInfo base class. Only the * function belonging to the primary AriadneHandler for the event to * be generated is called. This default implementation of the function * simply return one. The current sub-process is mixed together with * other processes with a multiplicity of outgoing particles between * \a minMult and \a maxMult. * @throws CKKWMultiplicityException if the minMult > maxMult or if * the number of outgoing particle is outside the specified range. */ virtual double reweightCKKW(int minMult, int maxMult); /** * Check if the particles in the dipole state passes the cuts from * lastXComb. */ bool passCuts(tcDipoleStatePtr state); public: /** @name Functions relating to the running coupling. */ //@{ /** * Strategy for \f$\alpha_S\f$. 0 means constant a constant * \f$\alpha_S\f$ with a value given by alpha0(). 1 means a leading * order running \f$\alpha_S\f$ with a \f$\Lambda_{QCD}\f$ given by * lambdaQCD(). -1 means take whatever is specified in the current * StandardModelBase object. */ inline RunningOption runningCoupling() const { return theRunningCoupling; } /** * The constant \f$\alpha_S\f$ to be used if runningCoupling() is 0. */ inline double alpha0() const { return theAlpha0; } /** * Return the \f$\alpha_S\f$ to be used for the given \a scale. */ double alphaS(Energy2 scale) const; /** * The \f$\Lambda_{QCD}\f$ to use in the one loop running * \f$\alpha_S\f$ if runningCoupling is 1 */ inline Energy lambdaQCD() const { return theLambdaQCD; } /** * An internal \f$\alpha_S\f$ object to be used if runningCoupling() * is internalRunning. */ inline Ptr::const_pointer internalAlphaS() const { return theInternalAlphaS; }; /** * Return the flavour thresholds used in calculating \f$\alpha_S\f$. */ inline const set & flavourThresholds() const { return theFlavourThresholds; } /** * The constant \f$\alpha_{EM}\f$ to be used. If zero, use whatever * is specified in the current StandardModelBase object. */ inline double alphaEM0() const { return theAlphaEM0; } /** * The number of different colour indices available to dipoles. */ inline int nCol() const { return theNCol; } /** * The number of possible flavours in a \f$g\to q\bar{q}\f$ splitting. */ inline int nFlav() const { return theNFlav; } //@} /** * Check if photon emission are switched on or off. */ inline bool photonEmissions() const { return thePhotonEmissions; } public: /** * Calculate the starting scale for the given DipoleState. */ Energy startingScale(const DipoleState & state) const; /** * If DIS-like scattered leptons are found in the given SubProcess, * return properly setup corresponding hard remnants. The * remnants will belong to the given DipoleState. */ pair findDISLeptons(SubProcess & sub, DipoleState & state) const; /** * If findDISLeptons() has found scattered leptons, find also the * scattered quarks in the SubProcess and return them as hard * remnants. The remnants will belong to the given DipoleState. */ pair findDISQuarks(pair leptons, SubProcess & sub, DipoleState & state) const; /** * Return a list of intermediate s-channel resonances in the given * SubProcess. Resonances which have decayed into further resonances * will come before their children in the list. */ tPVector resonances(SubProcess & sub) const; /** * Return the object responsible for radiating from decay products * from coloured resonances. */ tColourResonanceModelPtr colourResonanceModel() const { return theColourResonanceModel; } /** * Return the object responsible for radiating from remnants. */ const RemnantModel & remnantModel() const { return *theRemnantModel; } /** * Find, create and return the QCD dipoles in the given * DipoleState. */ vector findQCDDipoles(DipoleState & state) const; /** * Find, create and return the electro-magnetic dipoles in the given * DipoleState. */ vector findEMDipoles(DipoleState & state) const; /** * Check the given DipoleState for consistency. */ bool checkState(DipoleState &, tcEmPtr = tEmPtr()); /** * The cutoff in invariant transverse momentum for QCD emissions. */ inline Energy pTCut() const { return thePTCut; } /** * The cutoff in invariant transverse momentum for QED emissions. */ inline Energy pTCutEM() const { return thePTCutEM; } /** * The inverse extension of a hadron remnant. */ inline Energy softMu() const { return theSoftMu; } /** * The dimension assumed for the extension of a hadron remnant. */ inline double softAlpha() const { return theSoftAlpha; } /** * The dimension assumed for the extension of a perturbative remnant. */ inline double hardAlpha() const { return theHardAlpha >= 0? theHardAlpha: softAlpha(); } /** * The power in the suppression of radiation from extended dipoles. */ inline double beta() const { return theBeta; } /** * Get the strategy for purging gluons with too small transverse momentum. */ inline PurgeStrategy purgeStrategy() const { return thePurgeStrategy; } /** * Get the factor used to determine how far below the cutoff a gluon may be before it is purged. */ inline double purgeFactor() const { return thePurgeFactor; } /** * Return the vector of available reweighting objects. */ inline const vector & reweighters() const { return theReweighters; } /** * The maximum number of allowed emission in the cascade. */ inline int maxEmissions() const { return theMaxEmissions; } /** * Return the vector of available emitter objects. */ inline const vector & emitters() const { return theEmitters; } /** * Check if the given dipole state corresponds to a valid * Born-level state in a CKKW-L merging and return the scale * associated with that state. If not return the negative of the * scale associated with the state. */ Energy checkBornState(const DipoleState &) const; /** * Check if the given dipole state corresponds to a valid state from * a matrix element generator in a CKKW-L merging. */ bool checkTreeState(const DipoleState &) const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); public: /** * Exception class used if the outgoing multiplicity is out of range * or the maximum multiplicity is larger than the minimum in * reweightCKKW. */ struct CKKWMultiplicityException: Exception {}; /** * Exception class used if no reasonable state was reconstructed in * the CKKW-L algorithm. */ struct CKKWBornException: Exception {}; /** * Exception class used if the dipole state is not self consistant at * any stage of the cascade. */ struct IntegretyException: Exception {}; /** * Exception class indicating no model could be found when requested. */ struct MissingModel: public Exception {}; protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ - virtual void doinit() throw(InitException); + virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Return true if this object needs to be initialized before all * other objects because it needs to extract PDFs from the event * file. This version will return true if runningCoupling() returns * internalRunning and no internalAlphaS() object has been given. */ virtual bool preInitialize() const; //@} private: /** * Function used by the interface. */ Energy minPTCut() const; /** * Function used by the interface. */ Energy maxLambdaQCD() const; private: /** * Strategy for \f$\alpha_S\f$. 0 means constant a constant * \f$\alpha_S\f$ with a value given by alpha0(). 1 means a leading * order running \f$\alpha_S\f$ with a \f$\Lambda_{QCD}\f$ given by * lambdaQCD(). -1 means take whatever is specified in the current * StandardModelBase object. */ RunningOption theRunningCoupling; /** * The constant \f$\alpha_S\f$ to be used if runningCoupling() is * noRunning. */ double theAlpha0; /** * The \f$\Lambda_{QCD}\f$ to use in the one loop running * \f$\alpha_S\f$ if runningCoupling is simpleRunning. */ Energy theLambdaQCD; /** * An internal \f$\alpha_S\f$ object to be used if runningCoupling() * is internalRunning. */ Ptr::pointer theInternalAlphaS; /** * Scale factor used to multiply the emission scales in the argument * of \f$\alpha_S\f$. */ double scaleFactor; /** * The flavour thresholds used in calculating \f$\alpha_S\f$. */ set theFlavourThresholds; /** * The cutoff in invariant transverse momentum for QCD emissions. */ Energy thePTCut; /** * The constant \f$\alpha_{EM}\f$ to be used. If zero, use whatever * is specified in the current StandardModelBase object. */ double theAlphaEM0; /** * The cutoff in invariant transverse momentum for QED emissions. */ Energy thePTCutEM; /** * The number of different colour indices available to dipoles. */ int theNCol; /** * The number of possible flavours in a \f$g\to q\bar{q}\f$ splitting. */ int theNFlav; /** * Switch to turn on and off photon emission in the cascade. */ bool thePhotonEmissions; /** * The inverse extension of a hadron remnant. */ Energy theSoftMu; /** * The dimension assumed for the extension of a hadron remnant. */ double theSoftAlpha; /** * The dimension assumed for the extension of a hard remnant. */ double theHardAlpha; /** * The power in the suppression of radiation from extended dipoles. */ double theBeta; /** * A list of reweighting objects which may be applied to dipole * emissions. */ vector theReweighters; /** * The maximum number of emissions allowed in the cascade. */ int theMaxEmissions; /** * The vector of EmittorBase objects responsible for generating and * performing emissions according to the Dipole Cascade Model and * its extentions. */ vector theEmitters; /** * A vector of BornCheckerBase objects which are used in the CKKW-L * algorithm. */ vector theBornCheckers; /** * The object responsible for choosing the starting scale of the * shower. */ ScaleSetterPtr theScaleSetter; /** * The object responsible for identifying DIS-like event. */ DISFinderPtr theDISFinder; /** * The object responsible for identifying DIS-like event. */ ResonanceFinderPtr theResonanceFinder; /** * The Object responsible for identifying QCD Diploles. */ QCDFinderPtr theQCDFinder; /** * The Object responsible for identifying electro-magnetic Diploles. */ EMFinderPtr theEMFinder; /** * The object responsible for radiating from decay products from * coloured resonances. */ ColourResonanceModelPtr theColourResonanceModel; /** * The object responsible for radiating from remnants. */ RemnantModelPtr theRemnantModel; /** * The object responsible for checking the consistency of a DipoleState. */ CCheckPtr consistency; /** * If set true, the consistencyh checking of emissions in this * dipole state is suspended as the initial state was not * consistent. */ bool suspendConsistencyChecks; /** * The strategy for purging gluons with too small transverse momentum. */ PurgeStrategy thePurgeStrategy; /** * The factor used to determine how far below the cutoff a gluon may be before it is purged. */ double thePurgeFactor; /** * A map containing the states generated by reweight CKKW. The map * assiciates an XComb to a struct containing the dipole state, the * the clustering History and a boolean which specifies if the state * has the maximum parton multiplicity or not. */ struct CKKWState { HistoryPtr history; LorentzRotation rotation; bool maxMult; }; map theCKKWMap; private: /** * Histograms for debugging purposes. */ FactoryBase::tH1DPtr histswing, histall, histglue, histqq, histlam; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ AriadneHandler & operator=(const AriadneHandler &); }; } #endif /* Ariadne5_AriadneHandler_H */ diff --git a/Cascade/Models/FSGluonEmitter.cc b/Cascade/Models/FSGluonEmitter.cc --- a/Cascade/Models/FSGluonEmitter.cc +++ b/Cascade/Models/FSGluonEmitter.cc @@ -1,257 +1,299 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the FSGluonEmitter class. // #include "FSGluonEmission.h" #include "FSGluonEmitter.h" #include "Ariadne/Cascade/QCDDipole.h" #include "Ariadne/Cascade/DipoleState.h" #include "Ariadne/Cascade/AriadneHandler.h" #include "ThePEG/Utilities/SimplePhaseSpace.h" #include "ThePEG/Utilities/UtilityBase.h" #include "ThePEG/Utilities/Throw.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Repository/CurrentGenerator.h" +#include "ThePEG/Utilities/DebugItem.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Ariadne5; FSGluonEmitter::FSGluonEmitter() {} FSGluonEmitter::~FSGluonEmitter() {} IBPtr FSGluonEmitter::clone() const { return new_ptr(*this); } IBPtr FSGluonEmitter::fullclone() const { return new_ptr(*this); } bool FSGluonEmitter::canHandle(const DipoleBase & e) const { tcQCDPtr d = dynamic_ptr_cast(&e); if ( !d ) return false; if ( d->iPart()->special(d->oPart()) || d->oPart()->special(d->iPart()) ) return false; return true; } bool FSGluonEmitter::overrides(const EmitterBase &, DipoleBase &) const { return false; } double FSGluonEmitter:: gluonEngine(FSGluonEmission & e, Energy rhomin, Energy rhomax, Energy W, double C, double yint, int n1, int n3) { rhomax = sqrt(rndsud(2.0*C*yint, sqr(rhomax), sqr(rhomin))); if ( rhomax <= rhomin ) return -1.0; e.rho = rhomax; double ymax = acosh(0.5*W/rhomax); e.y = 2.0*ymax*UseRandom::rnd() - ymax; e.x1 = 1.0 - rhomax*exp( e.y)/W + e.y1 - e.y3; e.x3 = 1.0 - rhomax*exp(-e.y)/W + e.y3 - e.y1; if ( !check(e.x1, e.x3, e.y1, 0.0, e.y3) ) return 0.0; double weight = (pow(e.x1, n1) + pow(e.x3, n3))/2.0; weight *= 2.0*ymax/yint; // Special handling of heavy quarks, the 'dead-cone' effect. double xm = exp(2.0*e.y); weight *= 1.0 - (e.y1*xm + e.y3/xm)/(e.x1 + e.x3 - 1.0); return weight; } EmPtr FSGluonEmitter:: generate(const DipoleBase & dipole, Energy rhomin, Energy rhomax) const { const QCDDipole & d = dynamic_cast(dipole); double C = (d.iPart()->isG() || d.oPart()->isG()? 3.0/4.0: 2.0/3.0)/ Constants::pi; int n1 = d.iPart()->isG()? 3: 2; int n3 = d.oPart()->isG()? 3: 2; Energy2 S = d.sdip(); if ( S <= sqr(2.0*rhomin) ) return EmPtr(); Energy W = sqrt(S); double y1 = max(d.iPart()->momentum().mass2()/S, 0.0); double y3 = max(d.oPart()->momentum().mass2()/S, 0.0); FSGluonEmission e(*this, dipole, y1, y3); C *= preweight(e); rhomax = min(rhomax, W/2.0); double yint = 2.0*acosh(0.5*W/rhomin); while (true) { if ( rhomax <= rhomin ) return EmPtr(); double weight = gluonEngine(e, rhomin, rhomax, W, C, yint, n1, n3); if ( weight < 0.0 ) return EmPtr(); rhomax = e.rho; if ( weight == 0.0 ) continue; weight *= reweight(e); if ( weight > UseRandom::rnd() ) break; } // Save information in the Emission object. e.ymax = log(W/Current()->pTCut()); e.radiators.push_back(d.oPart()); e.radiators.push_back(d.iPart()); e.colourParent = d.iPart(); e.mainParent = e.antiColourParent = d.oPart(); e.pold = make_pair(d.iPart()->momentum(), d.oPart()->momentum()); // The main parent is the one which looses most energy. if ( sqr(e.x3) > UseRandom::rnd()*(sqr(e.x1) + sqr(e.x3)) ) { e.mainParent = d.iPart(); swap(e.radiators[0], e.radiators[1]); } return new_ptr(e); } bool FSGluonEmitter:: perform(const Emission & emission) const { QCDDipole & d = dynamic_cast(*emission.dipole); const FSGluonEmission & e = dynamic_cast(emission); tParPtr ip = d.iPart(); tParPtr op = d.oPart(); e.pold = make_pair(ip->momentum(), op->momentum()); try { e.genmom = getMomenta(d.sdip(), e.x1, e.x3, ip->momentum().mass(), ZERO, op->momentum().mass(), ip->isG(), op->isG(), rnd(2.0*Constants::pi), ip->momentum(), op->momentum()); } catch ( ImpossibleKinematics ) { return false; } LorentzRotation R = Utilities::getBoostFromCM(make_pair(ip->momentum(), op->momentum())); ip->momentum() = e.genmom.first; op->momentum() = e.genmom.third; tParPtr g = insertGluon(d, e.mainParent).first; g->momentum() = e.genmom.second; g->setVertex(R.inverse()*((sqr(e.x3)*(R*ip->vertex()) + sqr(e.x1)*(R*op->vertex()))/ (sqr(e.x3) + sqr(e.x1)))); g->emission(&e); e.partons.push_back(g); + static DebugItem swap2("Ariadne5::SwapSecond", 9); + static DebugItem swapfull("Ariadne5::SwapFull", 9); + bool swap = ( swap2 || swapfull ); + if ( !swap ) return true; + if ( swap2 && e.geno != 2 ) return true; + if ( swap2 && ip->isG() && op->isG() ) return true; + tParPtr q1, g2, g3, q4; + bool iside = ( e.mainParent == ip ); + + if ( iside ) { + if ( !ip->isG() ) return true; + if ( ip == d.iPart() ) + q1 = d.prev()->iPart(); + else + q1 = d.prev()->prev()->iPart(); + g2 = ip; + g3 = g; + q4 = op; + } else { + if ( !op->isG() ) return true; + q1 = ip; + g2 = g; + g3 = op; + if ( op == d.oPart() ) + q4 = d.next()->oPart(); + else + q4 = d.next()->next()->oPart(); + } + Energy2 s12 = (q1->momentum() + g2->momentum()).m2(); + Energy2 s34 = (g3->momentum() + q4->momentum()).m2(); + Energy2 s13 = (q1->momentum() + g3->momentum()).m2(); + Energy2 s24 = (g2->momentum() + q4->momentum()).m2(); + if ( ((s13*s24)/(s12*s34) + 1.0)*rnd() < 1.0 ) { + // cerr << "Swapping " << sqrt(s12)/GeV << "," << sqrt(s34)/GeV + // << " to " << sqrt(s13)/GeV << "," << sqrt(s24)/GeV <momentum(), g3->momentum()); + } else { + // cerr << "Not swapping " << sqrt(s12)/GeV << "," << sqrt(s34)/GeV + // << " to " << sqrt(s13)/GeV << "," << sqrt(s24)/GeV < FSGluonEmitter:: insertGluon(QCDDipole & d, tParPtr p) { pair ret; tParPtr g = ret.first = d.state()->create(CurrentGenerator()->getParticleData(ParticleID::g), p); tQCDPtr newd = ret.second = d.state()->create(); newd->colourIndex(d.colourIndex()); if ( !g || !newd ) Throw() << "Ariadne could not create new dipoles or partons." << Exception::abortnow; tParPtr ip = d.iPart(); tParPtr op = d.oPart(); ip->touch(); op->touch(); if ( d.next() ) d.next()->touch(); if ( d.prev() ) d.prev()->touch(); d.touch(); newd->iPart(g); newd->oPart(op); d.oPart(g); if ( d.next() ) d.next()->prev(newd); newd->next(d.next()); d.next(newd); newd->prev(&d); if ( op == p ) { newd->generateColourIndex(); g->origICol(op->origICol()); op->origICol(tColinePtr()); } else { d.generateColourIndex(); g->origOCol(ip->origOCol()); ip->origOCol(tColinePtr()); } return ret; } void FSGluonEmitter::removeGluon(QCDDipole & d, tParPtr g, tParPtr p) { tQCDPtr newd = d.next(); if ( p == d.iPart() ) { d.colourIndex(newd->colourIndex()); d.iPart()->origOCol(g->origOCol()); } else { newd->oPart()->origICol(g->origICol()); } d.oPart(newd->oPart()); d.next(newd->next()); if ( d.next() ) d.next()->prev(&d); d.iPart()->untouch(); d.oPart()->untouch(); if ( d.next() ) d.next()->untouch(); if ( d.prev() ) d.prev()->untouch(); d.state()->forgetParton(g); d.state()->forgetDipole(newd); } void FSGluonEmitter::revert(const Emission & emission) const { QCDDipole & d = dynamic_cast(*emission.dipole); const FSGluonEmission & e = dynamic_cast(emission); removeGluon(d, d.oPart(), e.mainParent); d.iPart()->setMomentum(e.pold.first); d.oPart()->setMomentum(e.pold.second); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FSGluonEmitter::persistentOutput(PersistentOStream &) const {} void FSGluonEmitter::persistentInput(PersistentIStream &, int) {} DescribeClass describeAriadne5FSGluonEmitter("Ariadne5::FSGluonEmitter", "libAriadne5.so"); void FSGluonEmitter::Init() { static ClassDocumentation documentation ("The FSGluonEmitter class implements the standard classical gluon " "emission from a final-state colour dipole."); } diff --git a/Cascade/Models/Makefile.am b/Cascade/Models/Makefile.am --- a/Cascade/Models/Makefile.am +++ b/Cascade/Models/Makefile.am @@ -1,35 +1,38 @@ mySOURCES = FSGluonEmission.cc FSGluonEmitter.cc FSQQEmission.cc FSQQEmitter.cc \ ColourChargeRegions.cc SpecialGluonEmission.cc \ SpecialGluonEmitter.cc RemnantModel.cc ColourResonanceModel.cc \ RemnantGluonEmission.cc ISGtoQEmission.cc ISQEmission.cc \ ISQEmitter.cc ISGtoQEmitter.cc ISQtoGEmitter.cc ISQtoGEmission.cc \ DISME.cc RemnantGluonEmitter.cc SpecialQQEmission.cc \ SpecialQQEmitter.cc RRGluonEmitter.cc RRGluonEmission.cc DYME.cc \ RecoilGluonEmitter.cc DipoleSwinger.cc DipoleSwing.cc DOCFILES = FSGluonEmission.h FSGluonEmitter.h FSQQEmission.h FSQQEmitter.h \ ColourChargeRegions.h SpecialGluonEmission.h SpecialGluonEmitter.h \ RemnantModel.h PseudoParton.h ColourResonanceModel.h \ RemnantGluonEmission.h ISGtoQEmission.h ISQEmission.h ISQEmitter.h \ ISGtoQEmitter.h ISQtoGEmitter.h ISQtoGEmission.h DISME.h \ RemnantGluonEmitter.h SpecialQQEmission.h SpecialQQEmitter.h DYME.h \ RRGluonEmitter.h RRGluonEmission.h RecoilGluonEmitter.h \ DipoleSwinger.h DipoleSwing.h INCLUDEFILES = $(DOCFILES) RemnantModel.fh ColourResonanceModel.fh noinst_LTLIBRARIES = libAriadne5Models.la libAriadne5Models_la_SOURCES = $(mySOURCES) $(INCLUDEFILES) include $(top_srcdir)/Config/Makefile.aminclude ..debug: cd ..; make debug +..lib: + cd ..; make + ..check: cd ../..; make check diff --git a/DIPSY/Diffract.in b/DIPSY/Diffract.in --- a/DIPSY/Diffract.in +++ b/DIPSY/Diffract.in @@ -1,118 +1,140 @@ cd /DIPSY read ./Tune31.in ## Now we set up an event generator. cp EventHandler DiffEventHandler set stdProton:R0 0.0 set stdAntiProton:R0 0.0 set Proton:R0 0.0 set AntiProton:R0 0.0 set DiffEventHandler:WFL stdProton set DiffEventHandler:WFR stdProton set DiffEventHandler:ConsistencyLevel 0 set DiffEventHandler:XSecFn:CheckOffShell false set DiffEventHandler:CascadeHandler NULL set DiffEventHandler:HadronizationHandler NULL set DiffEventHandler:DecayHandler NULL create ThePEG::FixedCMSLuminosity DiffLumi set DiffEventHandler:LuminosityFunction DiffLumi cp Generator DiffGenerator set DiffGenerator:EventHandler DiffEventHandler set DiffEventHandler:BGen:Width 5 set DiffEventHandler:EffectivePartonMode Colours erase DiffEventHandler:AnalysisHandlers[0] erase DiffEventHandler:AnalysisHandlers[0] create DIPSY::SemiInclusiveXSecAnalysis AnaSemi SemiInclusiveXSecAnalysis.so insert DiffEventHandler:AnalysisHandlers[0] AnaSemi create DIPSY::AnalysisProgress AnaLog AnalysisProgress.so set AnaLog:Interval 600 insert DiffEventHandler:AnalysisHandlers[0] AnaLog set DiffGenerator:EventHandler:DecayHandler NULL set DiffGenerator:EventHandler:HadronizationHandler NULL set DiffEventHandler:WFL Proton set DiffEventHandler:WFR Proton set DiffEventHandler:EventFiller:SoftRemove NoValence set /DIPSY/DiffEventHandler:BaryonSize 0.0 set FSSwinger:SetRmax -2.7 erase AriadneCascade:Emitters[0] set DiffEventHandler:CoherenceRange 3.9 insert AriadneCascade:Emitters[0] FSSwinger set DiffGenerator:EventHandler:CascadeHandler NULL set DiffGenerator:EventHandler:CascadeHandler AriadneCascade set DiffGenerator:EventHandler:FudgeME 1 set DiffEventHandler:EffectivePartonMode Colours set DiffEventHandler:CoherenceRange 2.5 set DiffGenerator:EventHandler:PreSamples 1000 set DiffGenerator:EventHandler:PreSampleB 100 set DiffGenerator:EventHandler:PreSampleL 10 set DiffGenerator:EventHandler:PreSampleR 10 do DiffGenerator:AddInterface /DIPSY/DiffEventHandler:YFrametest 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90 set DiffGenerator:DumpPeriod 0 set DiffEventHandler:LambdaQCD 0.22 set DiffEventHandler:Swinger:Lambda 1.0 set DiffEventHandler:RMax 3.21 set DiffEventHandler:Emitter:PMinusOrdering 0.92 set DiffGenerator:EventHandler:Emitter:PTScale 1.18 set stdFiller:PTCut 1 set DiffGenerator:NumberOfEvents 0 set DiffGenerator:EventHandler:LuminosityFunction:Energy 1800 saverun Diff1809l DiffGenerator set DiffGenerator:EventHandler:LuminosityFunction:Energy 7000 saverun Diff7009l DiffGenerator set DiffEventHandler:LambdaQCD 0.255 set DiffEventHandler:RMax 2.9 set DiffEventHandler:Emitter:PMinusOrdering 0.665 set DiffEventHandler:Emitter:PTScale 1.3 set DiffGenerator:EventHandler:LuminosityFunction:Energy 1800 saverun Diff1870l DiffGenerator set DiffGenerator:EventHandler:LuminosityFunction:Energy 7000 saverun Diff7070l DiffGenerator set DiffEventHandler:LambdaQCD 0.228 set DiffEventHandler:RMax 3.0 set DiffEventHandler:Emitter:PMinusOrdering 0.67 set DiffEventHandler:Emitter:PTScale 1.25 set DiffGenerator:EventHandler:LuminosityFunction:Energy 1800 saverun Diff1800l DiffGenerator set DiffGenerator:EventHandler:LuminosityFunction:Energy 7000 saverun Diff7000l DiffGenerator set DiffGenerator:EventHandler:PreSamples 100 set DiffGenerator:EventHandler:PreSampleB 100 set DiffGenerator:EventHandler:PreSampleL 10 set DiffGenerator:EventHandler:PreSampleR 10 saverun Diff7000a DiffGenerator set DiffGenerator:EventHandler:PreSamples 1000 set DiffGenerator:EventHandler:PreSampleB 10 set DiffGenerator:EventHandler:PreSampleL 10 set DiffGenerator:EventHandler:PreSampleR 10 saverun Diff7000b DiffGenerator set DiffGenerator:EventHandler:PreSamples 400 set DiffGenerator:EventHandler:PreSampleB 100 set DiffGenerator:EventHandler:PreSampleL 5 set DiffGenerator:EventHandler:PreSampleR 5 saverun Diff7000c DiffGenerator set DiffGenerator:EventHandler:PreSamples 4000 set DiffGenerator:EventHandler:PreSampleB 100 set DiffGenerator:EventHandler:PreSampleL 2 set DiffGenerator:EventHandler:PreSampleR 2 saverun Diff7000d DiffGenerator set DiffGenerator:EventHandler:PreSamples 40000 set DiffGenerator:EventHandler:PreSampleB 100 set DiffGenerator:EventHandler:PreSampleL 2 set DiffGenerator:EventHandler:PreSampleR 2 saverun Diff7000L DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 491 +saverun Diff7000M DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 42 +saverun Diff7000N DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 314 +saverun Diff7000O DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 7392 +saverun Diff7000P DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 9812 +saverun Diff7000Q DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 4760 +saverun Diff7000R DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 9212 +saverun Diff7000S DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 73924 +saverun Diff7000T DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 98122 +saverun Diff7000U DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 476077 +saverun Diff7000V DiffGenerator +set DiffGenerator:RandomNumberGenerator:Seed 922 +saverun Diff7000W DiffGenerator diff --git a/DIPSY/DiffractiveEventFiller.cc b/DIPSY/DiffractiveEventFiller.cc --- a/DIPSY/DiffractiveEventFiller.cc +++ b/DIPSY/DiffractiveEventFiller.cc @@ -1,1369 +1,1369 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the DiffractiveEventFiller class. // #include "DipoleEventHandler.h" #include "EventFiller.h" #include "DiffractiveEventFiller.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/Utilities/Current.h" #include "ThePEG/Utilities/Throw.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/EventRecord/Step.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/EventRecord/SubProcess.h" #include "RealPartonState.h" #include "ThePEG/Utilities/Debug.h" #include "ThePEG/Utilities/DebugItem.h" #include "ThePEG/Utilities/UtilityBase.h" #include "ThePEG/Utilities/SimplePhaseSpace.h" #include "ThePEG/Handlers/LuminosityFunction.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include #include using namespace DIPSY; DiffractiveEventFiller::DiffractiveEventFiller() {} DiffractiveEventFiller::~DiffractiveEventFiller() {} IBPtr DiffractiveEventFiller::clone() const { return new_ptr(*this); } IBPtr DiffractiveEventFiller::fullclone() const { return new_ptr(*this); } /* * Fills the step with a diffractive event. */ double DiffractiveEventFiller::fill(Step & step, DipoleEventHandler & eh, tPPair inc, DipoleState & dr, DipoleState & de, const ImpactParameters & b) const { //Some debugging set up. static DebugItem printsteps("DIPSY::PrintSteps", 6); static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); //Sets debugging output. //TODO: interface // bool printstepdetails = true; if ( printstepdetails ) cout << setprecision(6); if ( printstepdetails ) cout << "entered fill()" << endl; //evolve the valence state to maximum allowed rapidity for the excited state. //turn swing of for this. then revert for the virtual cascades later. double lambda = eh.swingPtr()->lambda(); //TODO: can this be set to 0? eh.swingPtr()->lambda(0.0000000000001); dr.evolve(dr.lowestY(), maxY()); eh.swingPtr()->lambda(lambda); if ( printstepdetails ) cout << "evolved real state" << endl; //to get the correct weight for the real cascade (specially the absence of //a "no more emissions after this" term for the real cascade), we need to //return an event for every subcascade. Or equivalently, and avoiding correlations //between the final states, returning one random subcascade weighted by the number //of subcascades. // //The selectionProbability is only used when running with nInteractions == -1, //and should be set to about 1/(the largest number of subcascades you expect in a //real cascade). Too low means that it will run through a lot of real cascades before //picking one (not too bad), and too high will give occasional events with very high //weight (potentially making the result untrustworthy). double selectionProbability = 1; //the weight the event receives in association with the choice of subcascade. double choiceWeight = 0.0; //this choice runs with any number of interactions. While producing an exact result, //it converges incredibly slowly, as the cross section will be dominated by a very small //fraction of the events (namely the ones with a single interacting large dipole). if ( nInteractions() < 0 ) { choiceWeight = selectSubcascade(dr, selectionProbability); } //No interacting dipoles means an elastic event. else if ( nInteractions() == 0 ) { pickSubcascade(dr, 0); increaseNSubCascades(1.0); choiceWeight = 1.0; } //A single interacting dipole. else if ( nInteractions() == 1 ) { choiceWeight = selectSingleSubcascade(dr); } //a fix number of interaction larger than 1. else if ( nInteractions() > 1 ) { choiceWeight = selectNSubcascade(dr, nInteractions()); } //if no subcascade chosen, start over. if ( choiceWeight == 0.0 ) { if ( printstepdetails ) cout << "choiceweight is 0, return 0 and start over." << endl; return 0.0; } double weight = choiceWeight; //identify the ends of the chains. These are treated differently than the rest in the //amplitude, so it is easier to identify them one time for all here. These are the circled //partons in fig 15 in the diffractive paper. vector chainCaps = childlessChildren(&dr); if ( printstepdetails ) cout << "found chaincaps " << chainCaps.size() << endl; //We now clean up the subcascade into a proper real finalstate. //Ie, do all the things you have to do to a virtual cascade to make it real, //like reweight the pt maxima, double check ordering etc. makeReal(dr, chainCaps, de); //The cleaning can mess up the interacting partons, although it shouldn't be very frequent. //but better to recheck and avoid troubles later on. chainCaps = childlessChildren(&dr); //check that the number of chaincaps (ie, interactions) in the real state is still the correct one. //they may go away if some interacting parton was not ordered etc. //if we run all numbers of interaction (-1 or -2), then it doesn't matter and we should always continue. if ( int(chainCaps.size()) != nInteractions() && nInteractions() > -1 ) { if ( printstepdetails ) cout << "got " << chainCaps.size() << " chainCaps, veto." << endl; return 0.0; } //if the subcascade doesnt reach up to minimum y (too low M_X^2), start over. if ( dr.highestY() < minY() ) { if ( printstepdetails ) cout << "too low highestY, return 0 and start over. needed " << minY() << ", got " << dr.highestY() << endl; return 0.0; } //estimate the amplitude and veto/reweight accordingly //this is to avoid running through all the elastic cascade for all excited states //that will get a very low amplitude anyways. // //I have some doubts on this method, as if the estimate is not accurate for all cascades //it may throw away high-amplitude cascade often, and give some events with very high weight. //However, tests has shown that the weight distribution looks a bit better with reweighting //like this, so I left it in. But keep track on the weight distribution and consider //switching this off (-2 interactions) if it gets worse. double estimate = reweightCascade(dr, chainCaps); if ( nInteractions() != -2 ) { if ( estimate == 0.0 ) { if ( printstepdetails ) cout << "estimated amplitude 0, probably not good." << endl; return 0.0; } //to estimate weight, we need to square the estimate of the amplitude. double passProb = sqr(estimate); //to tone down the reweighting a bit (specially to avoid spikes to high weights) //the square root of the estimated weight is used. passProb = sqrt(passProb); //throw away most of the cascades that seems to have low amplitude, but increase the weight //of the ones we do decide to run. if ( UseRandom::rnd() > passProb ) { return 0.0; } else weight /= passProb; //TODO: proper error message if ( isnan(weight) ) cout << "weight is not a number after interaction estimate." << endl; } //calculate the amplitude for this real cascade, by summing over virtual cascades. double amp = amplitude(dr, chainCaps, b); //probability is proportional to the square of the amplitude. weight *= sqr(amp); //TODO: proper error message if ( isnan(weight) ) cout << "weight is not a number after amplitude." << endl; if ( printstepdetails ) cout << "calculated amp^2 " << sqr(amp) << endl; if ( printstepdetails ) cout << "weight is now " << weight << endl; if ( printstepdetails ) cout << "number of gluons: " << dr.getPartons().size() << endl; //balance momenta by taking some energy from the elastic state to put //the excited state on shell. If this fails (usually due to not enough energy), //then throw the event away. if ( !balanceMomenta(&dr, &de) ) { if ( printstepdetails ) cout << "failed to balance momenta" << endl; return 0.0; } //add finalstate swing double yrange = FSSwingTime(); double ystep = FSSwingTimeStep(); for ( double y = 0.0; y < yrange; y += ystep ) { dr.swingFS(y, y + ystep); } //extract strings from the excited state. vector strings = dr.strings(); //mirrer elastic state to make it move in the opposite direction of the //excited state and turn it into a proton //This is will obviously have to be changed if diffracting on something //else than a proton. de.mirror(0.0); DipoleState::String protonString = makeProton(& de); //add elastic particle to the strings. strings.push_back(protonString); //fill step. Scrap event if something doesn't work. if ( strings.empty() || ! fillStep(step, inc, strings) ) { weight = 0.0; currentWeight = 0.0; //TODO: proper error message if ( printstepdetails ) cout << "empty string or failed fillstep, return 0" << endl; return weight; } if ( printstepdetails ) dr.diagnosis(true); //For really long runs, one could imagine that the elastic cascades should be //regenerated to reduce the error. Due to limited RAM on the computer //one cannot increase the number of elastic events to eb stored over a certain //number. Didn't turn out to really be needed yet though, thus commented out. // int CEN = generator()->currentEventNumber(); // int NEC = nElasticCascades(); // if ( double(CEN/NEC) == double(CEN)/double(NEC) ) { // cout << "generating new elastic cascades" << endl; // DipoleEventHandlerPtr eh = Current().ptr(); // DipoleStatePtr dummyState = eh->WFR().generate(*eh, 1000.0*GeV); // Energy W = dummyState->handler().lumiFn().maximumCMEnergy(); // Energy2 a = eh->WFR().m2() - eh->WFL().m2() + sqr(W); // Energy PR = (a + sqrt(sqr(a) - 4.0*eh->WFR().m2()*sqr(W)))*0.5/W; // initialiseVirtualCascades(*eh, eh->WFR(), PR, -maxY()); // cout << "done generating new elastic cascades" << endl; // } if ( printstepdetails ) cout << "done in DiffractiveEventFiller::fill(...), leaving." << endl; return weight; } /* * Some comments on this in the writeup. It is based on the version in the ND collisions. */ bool DiffractiveEventFiller::balanceMomenta(DipoleStatePtr excited, DipoleStatePtr elastic) const { //First calculate the p+ and p- of the excited state. Energy intPlus1 = ZERO; Energy intMinus1 = -excited->minus(); list partons = excited->getPartons(); for ( list::iterator it = partons.begin(); it != partons.end(); it++) { intPlus1 += (*it)->plus(); intMinus1 += (*it)->minus(); } //The p+ and p- of the elastic state. Reverse the + and -, due to not being mirrored yet, ie, both //the excited and elastic states have large p+ and low p- right now. Energy intPlus2 = -elastic->minus(); //TODO: should it really be "excited" here, not "elastic"? Compare to ND. Energy intMinus2 = excited->plus(); //solve the equation for: //x is the fraction of the p+ the excited state has to give to the elastic state. //y is the fraction of p- that it has to give to the excited state. Note however, that the elastic //state is not yet mirrored, so the roles of p+ and p- should be reversed. //Just set up some paramaters that apear in the solution. Energy2 A = intPlus1*intMinus2; Energy2 B = intPlus1*(intMinus1 - intMinus2) - intPlus2*intMinus2; Energy2 C = intPlus2*intMinus2; //This is what we have to take the square root of, so check it is positive. If not enough //energy, there will be no real solutions to get on shell. //TODO: proper error message. if ( sqr(B/(2*A)) - C/A < 0.0 ) { return false; } //The solution we are ineterested in. It is a 2:nd degree eq, but I am pretty sure this is the //solution we want. The other solution will make the two states bounce out almost the way they came //rather than just glancing of, as they should do (low-x, etc). The other has "- sqrt" instead. double y = -B/(2*A) + sqrt(sqr(B/(2*A)) - C/A); double x = 1.0 - intPlus2/(y*intPlus1); //this should not happen, but... if ( isnan(x) || isnan(y) || x <= 0.0 || y <= 0.0 ) { //TODO: proper error message. cout << "found negative or nan boosts in DifractiveEventFiller." << endl; return false; } //With x and y found, change the 4-momenta. for ( list::iterator it = partons.begin(); it != partons.end(); it++) { (*it)->plus(x*(*it)->plus()); (*it)->updateYMinus(); } //Again, elastic state not mirrored yet. elastic->plus(y*elastic->plus()); elastic->minus(elastic->minus()/y); return true; } /* * Had this in to calculate the inclusive cross section but I guess it should be called from * somewhere else. * TODO: is this done somewhere else? Comment if needed. */ void DiffractiveEventFiller::calculateInclusive(DipoleStatePtr real, CrossSection weight, const ImpactParameters & b) const { DipoleEventHandlerPtr eh = Current().ptr(); double prob = 0.0; for (int i = 0; i < int(virtualCascades.size()); i++ ) { double F = eh->xSecFn().sumf(*real, *virtualCascades[i], b); prob += eh->xSecFn().unitarize(F); } prob /= double(virtualCascades.size()); totalXSec += weight*sqr(prob); totalSqr += sqr(weight*sqr(prob)); neve++; } /* * */ double DiffractiveEventFiller::selectSubcascade(DipoleState & dr, double selectionProbability) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << "entering DiffractiveEventFiller::selectSubcascade(...)" << endl; //count the elastic subcascade this many times extra int elasticBoost = 10; //interface! tested that results do not depend on this variable //which gives that many extra subcascades effectively int nSub = nSubcascades(dr) + elasticBoost; if ( printstepdetails ) cout << "number of subcascade choices: " << nSub << endl; //choose if using this cascade, nsub*selProb double weight = nSub*selectionProbability; if ( printstepdetails ) cout << "weight is " << weight << endl; if ( isnan(weight) ) cout << "weight is not a number after cascade selection." << endl; double R = UseRandom::rnd(); if ( R > weight ) { if ( printstepdetails ) cout << "veto, try again with another real cascade" << endl; return 0.0; } //if passed veto with a 1 or less prob, set prob to 1 //larger probability than 1 has to go into the returned weight if ( weight < 1.0 ) weight = 1.0; if ( weight > 1.0 ) R *= weight; if ( printstepdetails ) cout << "passed selection veto, weight set to " << weight << endl; //select which subcascade using an integer between 0 and nSub int choice = int(R/selectionProbability); if ( printstepdetails ) cout << "pick subcascade no " << choice << endl; //identify it and modify dr accordingly //first check if it was one of the elastic ones, otherwise choose one normally //note that a choice of 0 corresponds to the elastic cascade if ( choice < elasticBoost + 1 ) { choice = 0; weight /= double(elasticBoost) + 1.0; if ( printstepdetails ) cout << "pick elastic, weight divided by " << double(elasticBoost) + 1.0 << ", now " << weight << endl; } else choice -= elasticBoost; if ( printstepdetails ) cout << "choice is " << choice << endl; if ( isnan(weight) ) cout << "weight is not a number after elastic boost" << endl; weight *= pickSubcascade(dr, choice); return weight; } void DiffractiveEventFiller::addPartonsToSet(DipolePtr d, set x) const { x.insert(d->partons().first); x.insert(d->partons().second); } double DiffractiveEventFiller::addRandomChain(DipoleState & dr) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << "entering DiffractiveEventFiller::selectSubcascade(...)" << endl; //first find the old partons and dipoles in a set list partons = dr.getPartons(); set oldP; for ( list::iterator it = partons.begin(); it != partons.end(); it++ ) oldP.insert(*it); //find the set of all partons set allP; set allD = dr.getAllDipoles(); for ( set::iterator it = allD.begin(); it != allD.end(); it++ ) addPartonsToSet(*it, allP); //remove the old partons for ( set::iterator it = oldP.begin(); it != oldP.end(); it++ ) allP.erase(*it); set newP = allP; if ( newP.empty() ) return 0.0; //pick one of the leftover partons as the new chain end (ie interaction) int choice = UseRandom::rnd()*newP.size(); set::iterator it = newP.begin(); while (choice > 0 ) { it++; choice--; } // addChainFromInteraction(dr,*it); return 0.0; } double DiffractiveEventFiller::selectSingleSubcascade(DipoleState & dr) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << "entering DiffractiveEventFiller::selectSubcascade(...)" << endl; list partons = dr.getPartons(); int nSub = countSingleStates(dr); if ( nSub == 0 ) return 0.0; if ( printstepdetails ) cout << "number of subcascade choices: " << nSub << endl; //count the number of possible subcascades. increaseNSubCascades(double(nSub)); //first find the valence partons vector dips = dr.initialDipoles(); set valP; for ( int i = 0; i < int(dips.size());i++) { valP.insert(dips[i]->partons().first); valP.insert(dips[i]->partons().second); } //remove the valence partons from the set of partons for ( list::iterator it = partons.begin(); it != partons.end(); it++ ) { PartonPtr p = *it; if ( valP.find(p) != valP.end() ) { it = partons.erase(it); it--; } } //pick one of the partons as the last emission (ie interaction) int choice = UseRandom::rnd()*partons.size(); list::iterator it = partons.begin(); while (choice > 0 ) { it++; choice--; } pickSubcascadeFromInteraction(dr,*it); return nSub; } double DiffractiveEventFiller::selectNSubcascade(DipoleState & dr, int N) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << "entering DiffractiveEventFiller::selectSubcascade(...)" << endl; if ( N < 1 ) cerr << "DiffractiveEventFiller::selectNSubcascade called with less than one interaction" << endl; double ret = selectSingleSubcascade(dr); int n = 1; while ( n < N ) { ret*= addRandomChain(dr); } //count the number of possible subcascades. increaseNSubCascades(double(ret)); return ret; } int DiffractiveEventFiller::countSingleStates(DipoleState & dr) const { list partons = dr.getPartons(); //count the valence partons vector dips = dr.initialDipoles(); set valP; for ( int i = 0; i < int(dips.size());i++) { valP.insert(dips[i]->partons().first); valP.insert(dips[i]->partons().second); } //return the number of excited states (partons - valP) return partons.size() - valP.size(); } int DiffractiveEventFiller::nSubcascades(DipoleState & dl) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << "entering DiffractiveEventFiller::nSubcascades(...)" << endl; int ret = 1; //iterate through valence dipoles and multiply number of combinations vector valDips = dl.initialDipoles(); if ( printstepdetails ) cout << "looking for subcascades of state:" << endl; // dl.plotState(true); for ( int i = 0; i < int(valDips.size()); i++ ) { ret *= nSubcascades(valDips[i]); } if ( printstepdetails ) cout << "found " << ret << " subcascsades" << endl; return ret; } int DiffractiveEventFiller::nSubcascades(DipolePtr dip) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); //a = 1 + b*c if 2 kids //a = b if one kid //a = 1 if no kids if ( dip->children().first && !dip->children().second ) { if ( printstepdetails ) cout << "found swung dipole in nsubcascades..." << endl; return nSubcascades(dip->children().first); } else if ( !dip->children().first && dip->children().second ) { return nSubcascades(dip->children().second); } else if ( dip->children().first && dip->children().second ) { return 1 + nSubcascades(dip->children().second)*nSubcascades(dip->children().first); } else { return 1; } } double DiffractiveEventFiller::pickSubcascade(DipoleState & dr, int choice) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); int configuration = choice; double weight = 1.0; //set all partons off shell setOffShell(dr); //mark the ones in the subcascade as on shell, by looping over the valence dips //this MAY have to be corrected with a swing. vector valDips = dr.initialDipoles(); for ( int i = 0; i < int(valDips.size()); i++ ) { //valence dips always real setPartonsOnShell(valDips[i]); //find the configuration number for this valence dipole //note that the max configuration number is the product of //the number of combinations in each valence dipole int N = nSubcascades(valDips[i]); int subconfiguration = configuration % N; //the remaining valence dips can choose between the config/N combinations. configuration /= N; if ( printstepdetails ) cout << "for this valence dip, use subconfiguration " << subconfiguration << " out of " << N << endl; //now look at this valence dipole. weight *= pickSubcascade(valDips[i], subconfiguration); } if ( printstepdetails ) cout << "done tagging onshells. now remove virtuals" << endl; // dr.plotState(true); //remove the off-shell ones removeVirtuals(& dr); if ( printstepdetails ) cout << "removed virtuals" << endl; //fix the parent structure that may get broken (REALLY?) when removing the virtuals //this is so that the real state will not run into troubles // updateParentStructure(&dr); return weight; } void DiffractiveEventFiller::pickSubcascadeFromInteraction(DipoleState & dr, PartonPtr p) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); //set all partons off shell setOffShell(dr); setValenceOnShell(dr); recursiveSetOnShell(p); //remove the off-shell ones removeVirtuals(& dr); if ( printstepdetails ) cout << "removed virtuals" << endl; //fix the parent structure that may get broken (REALLY?) when removing the virtuals //this is so that the real state will not run into troubles // updateParentStructure(&dr); } void DiffractiveEventFiller::recursiveSetOnShell(PartonPtr p) const { p->onShell(true); if ( p->parents().first ) recursiveSetOnShell(p->parents().first); if ( p->parents().second ) recursiveSetOnShell(p->parents().second); } double DiffractiveEventFiller::reweightCascade(DipoleState & dr, vector chainCaps) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( dr.getDipoles().size() == dr.initialDipoles().size() ) return min(1.0, estimateF(&dr)); vector realI = extractI(chainCaps); vector realH = extractH(chainCaps); double ret = 1.0; for ( int i = 0; i < int(realI.size()); i++ ) { double Fi = estimateF(realI[i]); double Gi = estimateF(realH[i]); //cout << ", (fi,Gi): (" << Fi << ", " << Gi << ")"; ret *= Fi-Gi; } //cout << endl; return min(1.0, ret); } double DiffractiveEventFiller::estimateF(DipoleStatePtr I) const { InvEnergy scale = 3.0/GeV; list dips = I->getDipoles(); double ret = 0.0; for ( list::iterator it = dips.begin(); it != dips.end(); it++ ) { DipolePtr dip = *it; ret += min(1.0, sqr(dip->size()/scale)); } return ret; } void DiffractiveEventFiller::setOffShell(DipoleState & dr) const { list partons = dr.getPartons(); for ( list::iterator it = partons.begin(); it != partons.end(); it++) { tPartonPtr p = *it; p->onShell(false); } } void DiffractiveEventFiller::setValenceOnShell(DipoleState & dr) const { vector dips = dr.initialDipoles(); for ( int i = 0; i < int(dips.size()); i++) { tPartonPtr p1 = dips[i]->partons().first; tPartonPtr p2 = dips[i]->partons().second; p1->onShell(true); p2->onShell(true); } } void DiffractiveEventFiller::setPartonsOnShell(DipolePtr dip) const { dip->partons().first->onShell(true); dip->partons().second->onShell(true); } double DiffractiveEventFiller::pickSubcascade(DipolePtr dip, int choice) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); //this dipole is always on shell. setPartonsOnShell(dip); int configuration = choice; //find out how many subcascades come from first child int firstN = dip->children().first? nSubcascades(dip->children().first):0; // int secondN = dip->children().second? nSubcascades(dip->children().second):0; //how much the no emissions case is boosted. INTERFACE!! //1 means default no emission, 2 means double probability. //double noEmBo = 1.0 + double(firstN*secondN)/3.0; //double noEmBo = 1.0; //as the no emission weights are changed, but the average weight has //to be maintained, a renormalisation is necessary //double weightNorm = (noEmBo + double(firstN*secondN))/ //(1.0+double(firstN*secondN)); // cout << "weightnorm: " << weightNorm << " options: " // << firstN*secondN << endl; if ( printstepdetails ) cout << "entering picksubcascade for a dipole with configuration number " << choice << endl; //configuration 0 is the one with no more emissions. if ( configuration == 0 ) { if ( printstepdetails ) cout << "this dipole has no further emissions" << endl; //reduce weight, as this option is more probable, see below // cout << "no emission 0, returning weight " << weightNorm/noEmBo << endl; //return weightNorm/noEmBo; return 1.0; } if ( !dip->children().first || !dip->children().second ) { Throw() << "Found a non-zero configuration number, but no children!! Will pretend configuration number is zero... :(" << Exception::warning; //return weightNorm/noEmBo; return 1.0; } //sometimes chose no emission anyways. //compensate this by reducing weight a factor 2 if that happens. //if ( UseRandom::rnd() < noEmBo/(noEmBo + double(firstN*secondN)) ) { // cout << "no emission 1, returning weight " << weightNorm/noEmBo << endl; //return weightNorm/noEmBo; //} // cout << "yes emission, emission options " << firstN*secondN << endl; //since no emission is excluded, remove 1 so that configuration is //between 0 and firstN*secondN configuration -= 1; if ( printstepdetails ) cout << "this dipole has (reduced) config number " << configuration << endl; //split up the configuration number into two independent numbers //one between 0 and firstN and one between 0 and secondN int firstConfiguration = configuration % firstN; int secondConfiguration = configuration/firstN; if ( printstepdetails ) cout << "split up into firstconf " << firstConfiguration << " (out of " << firstN << ")" << ", and second conf "<< secondConfiguration << " (out of " << nSubcascades(dip->children().second) << ")" << endl; //recur to each child with their respective configuration numbers //double weight = weightNorm; double weight = 1.0; weight *= pickSubcascade(dip->children().first, firstConfiguration); weight *= pickSubcascade(dip->children().second, secondConfiguration); // cout << "returning emitted weight " << weight << endl; //return weight; return 1.0; } void DiffractiveEventFiller::updateParentStructure(DipoleStatePtr dr) const { list partons = dr->getPartons(); for ( list::iterator it = partons.begin(); it != partons.end(); it++) { tPartonPtr p = *it; //dont bother with the offshell ones if ( !p->onShell() ) continue; //if the parent is off shell, take the grandparent as new parent while ( p->parents().first && !p->parents().first->onShell() ) p->parents(make_pair(p->parents().first->parents().first, p->parents().second)); while ( p->parents().second && !p->parents().second->onShell() ) p->parents(make_pair(p->parents().first, p->parents().second->parents().second)); } } //checks through all partons, and returns the ones without children. vector DiffractiveEventFiller::childlessChildren(DipoleStatePtr dr) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); list partons = dr->getPartons(); list childless = partons; //start with in the list, and remove the parents. //this is necessary as the partons do not remember their kids. while ( !partons.empty() ) { list offShells; for ( list::iterator it = partons.begin(); it != partons.end(); it++) { tPartonPtr p = *it; //remove parents from childless if ( p->parents().first ) { childless.remove(p->parents().first); } if ( p->parents().second ) { childless.remove(p->parents().second); } //save the off shell parents, as their parents in turn should not be counted as childless if ( p->parents().first && !p->parents().first->onShell() ) { offShells.push_back(p->parents().first); if ( printstepdetails ) cout << "found off shell at oy " << p->parents().first->oY() << endl; } if ( p->parents().second && !p->parents().second->onShell() ) { offShells.push_back(p->parents().second); if ( printstepdetails ) cout << "found off shell at oy " << p->parents().second->oY() << endl; } } partons = offShells; if ( printstepdetails ) cout << "found " << partons.size() << " off shell parents." << endl; } vector ret; for ( list::iterator it = childless.begin(); it != childless.end(); it++) { //first check that we don't add things without parents (ie valence) if ( !((*it)->parents().first) && !((*it)->parents().second) ) continue; ret.push_back(*it); } return ret; } //removes all valence partons in the vector void DiffractiveEventFiller::removeValence(vector partons) const { for ( vector::iterator it = partons.begin(); it != partons.end(); it++ ) { if ( (*it)->valence() ) { it = partons.erase(it); it--; } } } void DiffractiveEventFiller::makeReal(DipoleState & dr, vector chainCaps, DipoleState & de) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); //prepare by setting all partons off shell, they will then be set on shell //if they make it through the machinery setOffShell(dr); //create the real state RealPartonStatePtr rs = new_ptr(RealPartonState()); rs->addValence(dr); //run dr through a real state reweighting, with no interaction recoils //set interaction scale to that of the "interacting" dipoles for ( int i = 0; i < int(chainCaps.size()); i++ ) { if ( printstepdetails ) cout << "adding chainCap no " << i << endl; PartonPtr p = chainCaps[i]; //if already on-shell, nothing has to be done if ( p->onShell() ) continue; DipolePtr d1 = p->dipoles().first; DipolePtr d2 = p->dipoles().second; //first find the scale of the cap no i from the smallest connected dipole //this will set the pt scale the chain starts the non-DGLAP suppression from. Energy iScale = ZERO; if ( d1 && d2 ) iScale = p->pTScale()/min(d1->size(), d2->size()); else if ( d1 && !d2 ) iScale = p->pTScale()/d1->size(); else if ( !d1 && d2 ) iScale = p->pTScale()/d2->size(); else Throw() << "Found (childless) parton without dipoles in DiffractiveEventFiller::makeReal" << Exception::warning; //then run the machinery for reweighting and ordering if ( d1 ) rs->fullControlEvolution(d1, DipolePtr(), true, true, iScale, iScale); if ( d2 ) rs->fullControlEvolution(d2, DipolePtr(), true, true, iScale, iScale); //set the partons on shell if ( d1 ) rs->setOnShell(d1); if ( d2 ) rs->setOnShell(d2); } for ( RealParton::RealPartonSet::iterator it = rs->valence.begin(); it != rs->valence.end(); it++ ) { (*it)->setOnShell(); } //balance p- (and pt if overall recoil done) using dr //this then has to be inserted into the returned elastic particle RealPartonStatePtr ers = new_ptr(RealPartonState()); ers->addValence(de); fixBoost(rs, ers); if ( printstepdetails ) cout << "balanced p+-" << endl; //remove the virtuals in the dipole states rs->mergeVirtuals(); rs->saveState(); removeVirtuals(&dr); ers->saveState(); } double DiffractiveEventFiller::amplitude(DipoleState & dr, vector chainCaps, const ImpactParameters & b) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << setprecision(10); //make sure dr is in a state to be evolved and interact. //the state gets a bit messed up by reabsorbtion list dips = dr.getDipoles(); for ( list::const_iterator it = dips.begin(); it != dips.end(); it++ ) { DipolePtr d = *it; d->reset(); if ( d->neighbors().first && d->neighbors().first->colour() == d->colour() ) dr.generateColourIndex(d); if ( d->neighbors().second && d->neighbors().second->colour() == d->colour() ) dr.generateColourIndex(d); } DipoleEventHandlerPtr eh = Current().ptr(); // cout << "entering amplitude calculation for real state with " << chainCaps.size() // << " interactions" << endl; //first check if the state is the valence one, if so return the elastic amplitude. otherwise do the diffractive excitation amplitude if ( dr.getDipoles().size() == dr.initialDipoles().size() ) return elasticAmplitude(dr, b); //create one non-cap dipolestate (C) (these are the parents in the paper) DipoleStatePtr realC = steriliseCaps(&dr); //and for each cap: //one state of the two last dipoles (I_i) and one state of the second last dipole (X_i). vector realI = extractI(chainCaps); vector realH = extractH(chainCaps); //and the rapidities at which the caps were emitted. vector intY = extractIntY(chainCaps); //loop over virtual cascades from these real subcascades, pair each with a stored //virtual cascades from the elastic side, and calculate the averages of //cascadeNonInt (e^{F_U}) //hiddenInt: 1 - exp(-F_X_i) (for each i) //interactingInt: 1 - exp(-F_W_i) (for each i) double cascadeNonInt = 0.0; vector hiddenInt(realI.size(), 0.0); vector interactingInt(realI.size(), 0.0); vector hiddenInthalf(realI.size(), 0.0); vector interactingInthalf(realI.size(), 0.0); // cout << "vectors set up, starting loop" << endl; for (int i = 0; i < int(virtualCascades.size()); i++ ) { DipoleStatePtr virtU = realC->clone(); virtU->makeOriginal(); virtU->evolve(virtU->lowestY(), maxY()); double FU = eh->xSecFn().sumf(*virtU, *virtualCascades[i], b); cascadeNonInt += exp(-FU); for ( int j = 0; j < int(realI.size()); j++ ) { DipoleStatePtr virtW = realI[j]->clone(); virtW->makeOriginal(); virtW->evolve(intY[j], maxY()); double FWi = eh->xSecFn().sumf(*virtW, *virtualCascades[i], b); DipoleStatePtr virtX = realH[j]->clone(); virtX->makeOriginal(); virtX->evolve(intY[j], maxY()); double FXi = eh->xSecFn().sumf(*virtX, *virtualCascades[i], b); hiddenInt[j] += eh->xSecFn().unitarize(FXi); interactingInt[j] += eh->xSecFn().unitarize(FWi); if ( double(i) < double(virtualCascades.size())/2.0 ) { hiddenInthalf[j] += eh->xSecFn().unitarize(FXi); interactingInthalf[j] += eh->xSecFn().unitarize(FWi); } } } //normalise cascadeNonInt /= virtualCascades.size(); for ( int j = 0; j < int(realI.size()); j++ ) { hiddenInt[j] /= virtualCascades.size(); interactingInt[j] /= virtualCascades.size(); // cout << setprecision(10); // cout << "hidden: " << hiddenInt[j] << ", last: " << interactingInt[j] // << ", diff: " << interactingInt[j] - hiddenInt[j] << ", relative error: " // << (2.0*(interactingInthalf[j] - hiddenInthalf[j])/virtualCascades.size() - (interactingInt[j] - hiddenInt[j]))/(interactingInt[j] - hiddenInt[j]) // << ", parents: " << cascadeNonInt << endl; } //the final amplitude then is CascadeNonInt*hiddenNonInt*prod_i(interactingInti) double amp = cascadeNonInt; // cout << "cascade sudakov = " << cascadeNonInt; for ( int j = 0; j < int(realI.size()); j++ ) { // cout << ", interacting amplitude = " << interactingInt[j] // << ", hidden amplitude = " << hiddenInt[j] << endl; amp *= interactingInt[j] - hiddenInt[j]; } // cout << "returning amp " << amp << endl; return amp; } double DiffractiveEventFiller::elasticAmplitude(DipoleState & dr, const ImpactParameters & b) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << setprecision(10); cout << "elastic state. calculate elastic amplitude. dips: " << dr.getDipoles().size() << ", partons: " << dr.getPartons().size() << endl; DipoleEventHandlerPtr eh = Current().ptr(); // //testing // DipoleStatePtr newState = eh->WFR().generate(*eh, 200.0*GeV); // cout << "A completely new state:" << endl; // newState->coutData(); double amp = 0.0; double amphalf = 0.0; for (int i = 0; i < int(virtualCascades.size()); i++ ) { DipoleStatePtr virt = dr.clone(); virt->makeOriginal(); //DipoleStatePtr virt = copyActiveState(&dr); // DipoleStatePtr virtNew = eh->WFR().generate(*eh, 200.0*GeV); // set dipset = dr.allDipoles; // for ( set::const_iterator it = allDipoles.begin(); // it != allDipoles.end(); it++ ) { // } list newdips = virt->getDipoles(); // cout << "copied unevolved dips:" << endl; // for ( list::const_iterator it = newdips.begin(); it != newdips.end(); it++ ) { // DipolePtr d = *it; // cout << "address: " << d // << ", y1: " << d->partons().first->y() // << ", y2: " << d->partons().first->y() // << ", effective Parton 1: " << d->effectivePartons().first // << ", effective Parton 2: " << d->effectivePartons().second // << ", colour: " << d->colour() << endl; // } // newdips = virtNew->getDipoles(); // cout << "new dips:" << endl; // for ( list::const_iterator it = newdips.begin(); it != newdips.end(); it++ ) { // DipolePtr d = *it; // cout << "address: " << d // << ", y1: " << d->partons().first->y() // << ", child1: " << d->children().first // << ", child2: " << d->children().second // << ", generated gluon: " << d->generatedGluon() // << ", generatedy: " << d->generatedY() // << ", swingdip: " << d->swingDipole() // << ", colour: " << d->colour() << endl; // } if ( printstepdetails ) cout << "evolve from " << virt->lowestY() << " to " << maxY() << endl; virt->evolve(virt->lowestY(), maxY()); // cout << "copied state has " << virt->getPartons().size() << " partons." << endl; // virtNew->evolve(virtNew->lowestY(), maxY()); // cout << "new state has " << virtNew->getPartons().size() << " partons." << endl; double F = eh->xSecFn().sumf(*virt, *virtualCascades[i], b); F = eh->xSecFn().unitarize(F); if ( printstepdetails ) cout << "for elastic cascade " << i << ", elastic amp is = " << F << endl; amp += F; if ( double(i) < double(virtualCascades.size())/2.0 ) { amphalf += F; } } amp /= double(virtualCascades.size()); double relError = abs(2.0*amphalf/virtualCascades.size() - amp)/amp; double correctionFactor = 1.0/sqrt(1.0+sqr(relError)); //cout << "elastic amp: " << amp << ", relative error: " // << relError << ", correction factor: " << correctionFactor << endl; return amp*correctionFactor; } // DipoleStatePtr DiffractiveEventFiller::copyActiveState(DipoleStatePtr dr) const { // DipoleStatePtr copy = DipoleState(*dr); // list dips = dr->getDipoles(); // list ps = dr->getPartons(); // vector newPs; // for ( list::const_iterator it = dips.begin(); // it != dips.end(); it++ ) { // } // } //removes the chain caps from the state dr. DipoleStatePtr DiffractiveEventFiller::steriliseCaps(DipoleStatePtr dr) const { DipoleStatePtr state = dr->clone(); vector caps = childlessChildren(state); removeValence(caps); list parents = state->getDipoles(); // cout << "entering sterilisecaps, dipoles before: " << parents.size() // << ", caps: " << caps.size() << endl; for ( int i = 0; i < int(caps.size()); i++ ) { parents.remove(caps[i]->dipoles().first); parents.remove(caps[i]->dipoles().second); } // cout << "dipoles after: " << parents.size() << endl; if ( parents.size() == 0 ) { DipoleStatePtr ret = new_ptr(DipoleState()); ret->handler(Current().ptr()); return ret; } DipolePtr parent = *parents.begin(); // cout << "parent dipole is " << parent << endl; for ( int i = 0; i < int(caps.size()); i++ ) { DipolePtr d1 = caps[i]->dipoles().first; DipolePtr d2 = caps[i]->dipoles().second; d1->children().second = d2; d2->children().second = d1; PartonPtr p1 = d1->partons().first; PartonPtr p2 = d2->partons().second; // cout << "cap: " << caps[i]->oY(); // cout << ", p1: " << p1->oY(); // cout << ", p2: " << p2->oY() << endl; p1->removeChild(caps[i]); p2->removeChild(caps[i]); d1->turnOff(); d2->turnOff(); } return state; } vector DiffractiveEventFiller::extractI(vector chainCaps) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << "entering extract I" << endl; vector ret; for ( int i = 0; i < int(chainCaps.size()); i++ ) { PartonPtr c = chainCaps[i]; if ( printstepdetails ) cout << "set up cap" << endl; if ( !c->dipoles().first || !c->dipoles().second ) cerr << "quark chaincap in DEF::extractI!!!! :o" << endl; //make proper error message else { PartonPtr c1 = c->dipoles().first->partons().first; PartonPtr c2 = c->dipoles().second->partons().second; if ( printstepdetails ) cout << "create state, partons and dipoles" << endl; DipoleStatePtr state = new_ptr(DipoleState()); state->handler(Current().ptr()); PartonPtr p = new_ptr(Parton()); PartonPtr p1 = new_ptr(Parton()); PartonPtr p2 = new_ptr(Parton()); DipolePtr d1 = state->createDipole(); DipolePtr d2 = state->createDipole(); d1->partons(make_pair(p1, p)); d2->partons(make_pair(p, p2)); d1->neighbors(make_pair(DipolePtr(), d2)); d2->neighbors(make_pair(d1, DipolePtr())); d1->colour(c->dipoles().first->colour()); d2->colour(c->dipoles().second->colour()); p->plus(c->plus()); p->pT(c->pT()); p->updateYMinus(); p->oY(p->y()); p->position(c->position()); p->dipoles(make_pair(d1, d2)); p1->plus(c1->plus()); p1->pT(c1->pT()); p1->updateYMinus(); p1->oY(p1->y()); p1->position(c1->position()); p1->dipoles(make_pair(DipolePtr(), d1)); p2->plus(c2->plus()); p2->pT(c2->pT()); p2->updateYMinus(); p2->oY(p2->y()); p2->position(c2->position()); p2->dipoles(make_pair(d2, DipolePtr())); state->addDipole(*d1); state->addDipole(*d2); // cout << "L dip sizes: " << d1->size()*GeV << ", " // << d2->size()*GeV; if ( printstepdetails ) cout << "extracted I" << endl; // state->plotState(true); ret.push_back(state); } } return ret; } vector DiffractiveEventFiller::extractH(vector chainCaps) const { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); vector ret; for ( int i = 0; i < int(chainCaps.size()); i++ ) { PartonPtr c = chainCaps[i]; if ( !c->dipoles().first || !c->dipoles().second ) cerr << "quark chaincap in DEF::extractH!!!! :o" << endl; //make proper error message else { PartonPtr c1 = c->dipoles().first->partons().first; PartonPtr c2 = c->dipoles().second->partons().second; DipoleStatePtr state = new_ptr(DipoleState()); state->handler(Current().ptr()); PartonPtr p1 = new_ptr(Parton()); PartonPtr p2 = new_ptr(Parton()); DipolePtr d = state->createDipole(); d->partons(make_pair(p1, p2)); d->neighbors(make_pair(DipolePtr(), DipolePtr())); InvEnergy r1 = (c->position() - c1->position()).pt(); InvEnergy r2 = (c->position() - c2->position()).pt(); double P1 = sqr(r2)/(sqr(r1) + sqr(r2)); double P2 = 1.0 - P1; if ( P1 > 0.5 ) d->colour(c->dipoles().first->colour()); else d->colour(c->dipoles().second->colour()); p1->plus(c1->plus() + P1*c->plus()); p1->pT(c1->pT() + P1*c->pT()); p1->updateYMinus(); p1->oY(p1->y()); p1->position(c1->position()); p1->dipoles(make_pair(DipolePtr(), d)); p2->plus(c2->plus() + P2*c->plus()); p2->pT(c2->pT() + P2*c->pT()); p2->updateYMinus(); p2->oY(p2->y()); p2->position(c2->position()); p2->dipoles(make_pair(d, DipolePtr())); state->addDipole(*d); // cout << ", H dip sizes: " << d->size()*GeV << endl; if ( printstepdetails ) cout << "extracted H" << endl; // state->plotState(true); ret.push_back(state); } } return ret; } vector DiffractiveEventFiller::extractIntY(vector chainCaps) const { vector ret; for ( int i = 0; i < int(chainCaps.size()); i++ ) { ret.push_back(chainCaps[i]->oY()); // cout << "intY is " << chainCaps[i]->oY() << ", "; } return ret; } DipoleState::String DiffractiveEventFiller::makeProton(DipoleStatePtr state) const { DipoleState::String ret; PartonPtr proton = new_ptr(Parton()); proton->plus(state->plus()); proton->minus(state->minus()); proton->pT(TransverseMomentum()); ret.push_back(proton); proton->flavour(ParticleID::pplus); return ret; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). -void DiffractiveEventFiller::doinit() throw(InitException) { +void DiffractiveEventFiller::doinit() { EventFiller::doinit(); totalXSec = ZERO; totalSqr = ZERO; neve = 0; } void DiffractiveEventFiller::dofinish() { EventFiller::dofinish(); totalXSec /= double(neve); totalSqr /= double(neve); CrossSection err = sqrt(totalSqr - sqr(totalXSec))/double(neve); generator()->log() << "inclusive elastic plus SD (up to this y) cross section is " << ouniterr(totalXSec, err, nanobarn) << " nb." << endl; generator()->log() << "total number of subcascades encountered: " << nSubCascades() << endl; } void DiffractiveEventFiller::doinitrun() { EventFiller::doinitrun(); static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << "entering DiffractiveEventHandler doinitrun" << endl; DipoleEventHandlerPtr eh = Current().ptr(); DipoleStatePtr dummyState = eh->WFR().generate(*eh, 1000.0*GeV); Energy W = dummyState->handler().lumiFn().maximumCMEnergy(); Energy2 a = eh->WFR().m2() - eh->WFL().m2() + sqr(W); Energy PR = (a + sqrt(sqr(a) - 4.0*eh->WFR().m2()*sqr(W)))*0.5/W; double elasticY = log(PR/sqrt(eh->WFR().m2())); maxY(elasticY - minRapGap()); minY(elasticY - maxRapGap()); initialiseVirtualCascades(*eh, eh->WFR(), PR, -maxY()); } void DiffractiveEventFiller::persistentOutput(PersistentOStream & os) const { os << theNElasticCascades << theMinRapGap << theMaxRapGap << theMinY << theMaxY << theNInteractions; } void DiffractiveEventFiller::persistentInput(PersistentIStream & is, int) { is >> theNElasticCascades >> theMinRapGap >> theMaxRapGap >> theMinY >> theMaxY >> theNInteractions; } DescribeClass describeDIPSYDiffractiveEventFiller("DIPSY::DiffractiveEventFiller", "libAriadne5.so libDIPSY.so"); void DiffractiveEventFiller::Init() { static ClassDocumentation documentation ("The DiffractiveEventFiller class is able to produce an initial ThePEG::Step " "from two colliding DipoleStates."); static Parameter interfaceNElasticCascades ("NElasticCascades", "How many pregenerated elastic cascades should be used in the average over virtual cascades.", &DiffractiveEventFiller::theNElasticCascades, 0, 1, 0, true, false, Interface::lowerlim); static Parameter interfaceMinRapGap ("MinRapGap", "The minimum rapidity gap in the generated (gluonic) events. There may be some leak due to " "FSR and hadronisation", &DiffractiveEventFiller::theMinRapGap, 3.0, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfaceMaxRapGap ("MaxRapGap", "The maximum rapidity gap in the generated (gluonic) events. There may be some leak due to " "FSR and hadronisation", &DiffractiveEventFiller::theMaxRapGap, 5.0, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfaceNInteractions ("NInteractions", "The number of interactions in the events being sampled." "0 is elastic" "-1 is the old algorithm with reweighting (seems to converge a bit faster)" "-2 is the old algorithm without reweighting (slower for the tested runs, but " "may be better for other runs.", &DiffractiveEventFiller::theNInteractions, -2, 0, 0, true, false, Interface::lowerlim); } //ymax should be the M_x limit, and the real state should be evolved to meet the virtuals void DiffractiveEventFiller::initialiseVirtualCascades (DipoleEventHandler & eh, WaveFunction & WFR, Energy E, double ymax) { static DebugItem printstepdetails("DIPSY::PrintStepDetails", 6); if ( printstepdetails ) cout << "entering initialise virtual cascades" << endl; virtualCascades.clear(); int virtualSamples = nElasticCascades(); generator()->log() << "evolving elastic from " << -eh.WFR().generate(eh, E)->lowestY() << " to " << -ymax << endl; for ( int i = 0; i < virtualSamples; i ++ ) { DipoleStatePtr virt = eh.WFR().generate(eh, E); virt->evolve(virt->lowestY(), ymax); virtualCascades.push_back(virt); // if ( printstepdetails ) cout << "done virtual state no " << i << endl; // virt->plotState(true); } } diff --git a/DIPSY/DiffractiveEventFiller.h b/DIPSY/DiffractiveEventFiller.h --- a/DIPSY/DiffractiveEventFiller.h +++ b/DIPSY/DiffractiveEventFiller.h @@ -1,486 +1,486 @@ // -*- C++ -*- #ifndef DIPSY_DiffractiveEventFiller_H #define DIPSY_DiffractiveEventFiller_H // // This is the declaration of the DiffractiveEventFiller class. // #include "EventFiller.h" #ifndef LWH_AIAnalysisFactory_H #ifndef LWH #define LWH ThePEGLWH #endif #include "ThePEG/Analysis/LWH/AnalysisFactory.h" #endif namespace DIPSY { using namespace ThePEG; /** * The EventFiller class is able to produce an initial * ThePEG::Collision from two colliding DipoleStates. * * @see \ref EventFillerInterfaces "The interfaces" * defined for EventFiller. */ class DiffractiveEventFiller: public EventFiller { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ DiffractiveEventFiller(); /** * The destructor. */ virtual ~DiffractiveEventFiller(); //@} public: /** * Exception class for errors in the combinators in the diffractive cascades. */ struct DiffractiveCombinatorics: public Exception {}; /** * Exception class for incorrect cascade structures. */ struct CascadeStructure: public Exception {}; public: /** @name Virtual functions which can be overridden in subclasses. */ //@{ /** * Fill the current collision object in the given DipoleEventHandler * with the final state gluons produced when dipole states \a dl and * \a dr collides with impact parameters \a b. * @return the total interaction probability. */ /** * Fill the current collision object in the given DipoleEventHandler * with the final state gluons produced when the dipole state \a dl * diffractively scatters of the virtual states stored in the eventfiller. * @return the total interaction probability. */ virtual double fill(Step & step, DipoleEventHandler & eh, tPPair inc, DipoleState & dl, DipoleState & dr, const ImpactParameters & b) const; /** * transfer p_minus and p_plus from the elastic state to set the excited state on shell. **/ virtual bool balanceMomenta(DipoleStatePtr excited, DipoleStatePtr elastic) const; /** * calculates and logs the contribution to the total diffractive cross section. **/ virtual void calculateInclusive(DipoleStatePtr real, CrossSection weight, const ImpactParameters & b) const; /** * prepares the virtual cascades that all the real states will collide against. **/ virtual void initialiseVirtualCascades(DipoleEventHandler & eh, WaveFunction & WFL, Energy E, double ymax); /** * randomly selects one of the subcascades of dr with a certain probability for each subcascade * and turns dl into that subcascade. * returns the weight to be given to the event (0 if no subcascade is chosen) **/ virtual double selectSubcascade(DipoleState & dr, double selectionProbability) const; /** * randomly selects one of the partons that is not on-shell * and puts that parton and its parents on shell in the state. **/ virtual double addRandomChain(DipoleState & dr) const; /** * randomly selects one of the single-interaction subcascades of dr with * a certain probability for each subcascade * and turns dl into that subcascade. * returns the weight to be given to the event (0 if no subcascade is chosen) **/ virtual double selectSingleSubcascade(DipoleState & dr) const; /** * randomly selects one of the subcascades of dr with N interactions * and turns dl into that subcascade. * returns an approximation of the number of possible choices **/ virtual double selectNSubcascade(DipoleState & dr, int N) const; /** * coutns the number of subcacscades with exactly one interaction **/ virtual int countSingleStates(DipoleState & dr) const; /** * counts and returns the number of subcascades of the state **/ virtual int nSubcascades(DipoleState & dr) const; /** * changes the state to its substate of choice. **/ virtual double pickSubcascade(DipoleState & dr, int choice) const; /** * changes the state to its substate o. **/ virtual void pickSubcascadeFromInteraction(DipoleState & dr, PartonPtr p) const; /** * adds a parton and its parents to the on-shell state. **/ // virtual void addChainFromInteraction(DipoleState & dr, PartonPtr p) const; /** * adds the two partons of the dipole to the set x. **/ virtual void addPartonsToSet(DipolePtr d, set x) const; /** * Set the parton and all its ancestors on shell. **/ virtual void recursiveSetOnShell(PartonPtr p) const; /** * return more likely cascades and removes(return 0.0) less likely ones. * A state with small dipole will probably get removed, but the ones that doesnt are returned with * a larger weight. **/ double reweightCascade(DipoleState & dr, vector chainCaps) const; /** * return more likely cascades and removes(return 0.0) less likely ones. * A state with small dipole will probably get removed, but the ones that doesnt are returned with * a larger weight. **/ double estimateF(DipoleStatePtr dr) const; /** * sets all the partons in the state to off-shell **/ virtual void setOffShell(DipoleState & dr) const; /** * sets all the valence partons in the state on-shell. **/ virtual void setValenceOnShell(DipoleState & dr) const; /** * sets the two partons in the dipole on shell. **/ virtual void setPartonsOnShell(DipolePtr dip) const; /** * changes the subcascade from the dipole to its substate of choice. **/ virtual double pickSubcascade(DipolePtr dip, int choice) const; /** * checks and fixes the parent structure so that the on shell partons only * are connected to each other. The others are bypassed. * This may leave some partons without children if the swing is present. **/ virtual void updateParentStructure(DipoleStatePtr dr) const; /** * finds the nonvalence partons that does not have any children. * These are at the end of the chains, and can loosely be interpreted as the interactions. **/ virtual vector childlessChildren(DipoleStatePtr dr) const; /** * removes all valence partons from the provided vector **/ virtual void removeValence(vector partons) const; /** * counts and returns the number of subcascades from this dipole **/ virtual int nSubcascades(DipolePtr dip) const; /** * makes dl real and on-shell and does all the reweighting and ordering bussiness. * p- (and pt) is balances by dr, but dr is otherwise not touched. **/ virtual void makeReal(DipoleState & dl, vector chainCaps, DipoleState & dr) const; /** * Calculates the amplitude for the real state dr to diffractively scatter on * the virtual cascades stored in the eventfiller. **/ virtual double amplitude(DipoleState & dr, vector chainCaps, const ImpactParameters & b) const; /** * Calculates the elastic amplitude for dr on the virtual cascades stored in the eventfiller. **/ virtual double elasticAmplitude(DipoleState & dr, const ImpactParameters & b) const; /** * removes the chain caps from the state dr. * Returns true if there is still at least one dipole left. **/ virtual DipoleStatePtr steriliseCaps(DipoleStatePtr dr) const; /** * returns a DipoleState with the two neighbouring dipoles to each parton in the vector. **/ virtual vector extractI(vector chainCaps) const; /** * returns a DipoleState with the dipole that emitted each parton in the vector. **/ virtual vector extractH(vector chainCaps) const; /** * returns the original emission rapidity for each parton in the vector. **/ virtual vector extractIntY(vector chainCaps) const; /** * returns a string with a single proton with the 3-momentum of the original state **/ virtual DipoleState::String makeProton(DipoleStatePtr) const; //inline functions /** * get the mode. */ inline int nElasticCascades() const { return theNElasticCascades; } /** * set the mode. */ inline void nElasticCascades(int x) { theNElasticCascades = x; } /** * get the minimum rapidity gap. */ inline double minRapGap() const { return theMinRapGap; } /** * set the minimum rapidity gap. */ inline void minRapGap(double x) { theMinRapGap = x; } /** * get the number of interactions. */ inline int nInteractions() const { return theNInteractions; } /** * set the number of interactions. */ inline void nInteractions(int x) { theNInteractions = x; } /** * get the maximum rapidity gap. */ inline double maxRapGap() const { return theMaxRapGap; } /** * set the maximum rapidity gap. */ inline void maxRapGap(double x) { theMaxRapGap = x; } /** * get the minimum rapidity. */ inline double minY() const { return theMinY; } /** * set the minimum rapidity. */ inline void minY(double x) { theMinY = x; } /** * get the maximum rapidity. */ inline double maxY() const { return theMaxY; } /** * set the maximum rapidity. */ inline void maxY(double x) { theMaxY = x; } /** * reset the number of subcascades. */ inline void resetNSubCascades() { theNSubCascades = 0.0; } /** * increase the number of subcascades. */ inline void increaseNSubCascades(double x) const { theNSubCascades += x; } /** * reset the number of subcascades. */ inline double nSubCascades() { return theNSubCascades; } //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ - virtual void doinit() throw(InitException); + virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Is this where this should be declared?? :o */ virtual void dofinish(); private: mutable CrossSection totalXSec; mutable DipoleAnalysisHandler::CrossSection2 totalSqr; mutable int neve; private: //The linera combination of virtual cascades from the elastic particle vector virtualCascades; //the number of pregenerated elstic cascades int theNElasticCascades; //the minimum rapidity gap double theMinRapGap; //the number of interactions int theNInteractions; //the total number of subcascades encountered mutable double theNSubCascades; //the maximum rapidity gap double theMaxRapGap; //the minimum rapidity that every excited state cross. double theMinY; //the maximum rapidity that no excited state cross. double theMaxY; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ DiffractiveEventFiller & operator=(const DiffractiveEventFiller &); }; } #endif /* DIPSY_DiffractiveEventFiller_H */ diff --git a/DIPSY/DipoleAnalysisHandler.h b/DIPSY/DipoleAnalysisHandler.h --- a/DIPSY/DipoleAnalysisHandler.h +++ b/DIPSY/DipoleAnalysisHandler.h @@ -1,142 +1,142 @@ // -*- C++ -*- #ifndef DIPSY_DipoleAnalysisHandler_H #define DIPSY_DipoleAnalysisHandler_H // // This is the declaration of the DipoleAnalysisHandler class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/Analysis/FactoryBase.h" #include "DipoleAnalysisHandler.fh" #include "Ariadne/DIPSY/DipoleState.fh" #include "Ariadne/DIPSY/ImpactParameters.h" #include "Ariadne/DIPSY/DipoleXSec.fh" namespace DIPSY { using namespace ThePEG; /** * The DipoleAnalysisHandler class can be used as a base class for * sub-classes which can be used in the initialization of a * DipoleEventHandler, where statistics on, eg. total and elastic * cross sections, can be collected during the presampling phase. * * @see \ref DipoleAnalysisHandlerInterfaces "The interfaces" * defined for DipoleAnalysisHandler. */ class DipoleAnalysisHandler: public HandlerBase { public: /** * Convenient typedef */ typedef vector< vector< vector > > Vec3D; /** * Convenient typedef. */ - typedef Qty<4,0,0> CrossSection2; + typedef decltype(CrossSection()*CrossSection()) CrossSection2; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ DipoleAnalysisHandler(); /** * The destructor. */ virtual ~DipoleAnalysisHandler(); //@} public: /** @name Standard virtual functions to be overridden in sub-classes. */ //@{ /** * Initialize the analysis object. */ virtual void initialize() = 0; /** * Analyze a given collision given left- and right-moving dipole * states, \a dl and \a dr, an ImpactParameters object, \a b, a * cross section object, \a xsec, the total summed dipole-dipole * scattering probabilities, \a fsum, and the total \a weight * associated with the generated states. */ virtual void analyze(const DipoleState & dr, const DipoleState & dl, const ImpactParameters & b, const DipoleXSec & xsec, double fsum, CrossSection weight); /** * Analyze a given set of collision given a set of left- and * right-moving dipole states in \a vl and \a vr, an a set of * ImpactParameters object in \a vb, and a cross section object, \a * xsec, and the total summed dipole-dipole scattering * probabilities, \a probs. Also a jacobian, \a jac, is supplied in * case of varying total energy. */ virtual void analyze(const vector & vr, const vector & vl, const vector & vb, const DipoleXSec & xsec, const Vec3D & probs, double jac); /** * Finalize the analysis, (compute statistics etc.). \a neve is the * number of times analyze() has been called since last * initialize(). */ virtual void finalize(long neve) = 0; //@} /** * Return a pointer to the FactoryBase object of this run */ inline tHistFacPtr factory() const { return generator()->histogramFactory(); } /** * Return a pointer to the FactoryBase object of this run */ inline AIDA::IHistogramFactory & histogramFactory() const { return generator()->histogramFactory()->histogramFactory(); } /** * Write out stub for output line. */ ostream & stub(string) const; /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ DipoleAnalysisHandler & operator=(const DipoleAnalysisHandler &); }; } #endif /* DIPSY_DipoleAnalysisHandler_H */ diff --git a/DIPSY/DipoleEventHandler.cc b/DIPSY/DipoleEventHandler.cc --- a/DIPSY/DipoleEventHandler.cc +++ b/DIPSY/DipoleEventHandler.cc @@ -1,935 +1,954 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the DipoleEventHandler class. // #include "DipoleEventHandler.h" #include "SimpleProtonState.h" #include "PhotonDipoleState.h" #include "Parton.h" #include "OldStyleEmitter.h" #include "ThePEG/Interface/Switch.h" #include "PT1DEmitter.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Handlers/LuminosityFunction.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Config/algorithm.h" #include "gsl/gsl_sf_bessel.h" #include "ThePEG/Utilities/Current.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/PDF/PartonExtractor.h" #include "ThePEG/Utilities/Debug.h" #include "ThePEG/Utilities/DebugItem.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "CPUTimer.h" #include #include using namespace DIPSY; DipoleEventHandler::DipoleEventHandler() : EventHandler(false), theNColours(9), theRMax(3.5*InvGeV), theM0(0.0*GeV), thePTScale(2.0), theBaryonSize(0.0*InvGeV), theCoherenceRange(0.5*InvGeV), theEffectivePartonMode(0), theCollisionType(0), doShowHistory(false), theLambdaQCD(0.22*GeV), theNF(0), theFixedAlphaS(0.0), theExternalAlphaS(ASPtr()), theWFR(WaveFunctionPtr()), theWFL(WaveFunctionPtr()), theBGen(ImpactParameterGeneratorPtr()), theYFrame(0.5), theNoFrame(0), theFudgeME(0), theFudgeFactorME(1.0), thePreSamples(1000), thePreSampleL(1), thePreSampleR(1), thePreSampleB(1), theXSecFn(DipoleXSecPtr()), theEmitter(EmitterPtr()), theSwinger(SwingerPtr()) {} DipoleEventHandler::~DipoleEventHandler() {} IBPtr DipoleEventHandler::clone() const { return new_ptr(*this); } IBPtr DipoleEventHandler::fullclone() const { return new_ptr(*this); } double DipoleEventHandler::elapsed() { static long last = 0; long el = clock() - last; last += el; return double(el)*0.000001; } void DipoleEventHandler::presample() { //redirect diffractive runs, as the cross section calculation //then requires more than a single loop over collisions. if ( collisionType() == 1 ) return diffractivePresample(); //Set up before the loop Current current(this); for_each(analyses, mem_fun(&DipoleAnalysisHandler::initialize)); CrossSection xmax = 0.0*picobarn; CrossSection xnmax = 0.0*picobarn; elapsed(); generator()->log() << endl << "Starting DIPSY run at CoM energy " << lumiFn().maximumCMEnergy()/GeV << " GeV" << endl; //Loop over collisions for ( int i = 0, N = preSamples(); i < N; ++i ) { //Setup before collision. Energy, jacobian, luminosity. Energy W = lumiFn().maximumCMEnergy(); double jac = 1.0; pair ll(1.0, 1.0); if ( int ndim = lumiFn().nDim(make_pair(WFL().particle(), WFR().particle())) ) { vector r = UseRandom::rndvec(ndim); ll = lumiFn().generateLL(&(r[0]), jac); W *= exp(-0.5*(ll.first + ll.second)); } //Find the p+ (or p-) of each state. Energy2 a = WFL().m2() - WFR().m2() + sqr(W); Energy PL = (a + sqrt(sqr(a) - WFL().m2()*sqr(W)))*0.5/W; a = WFR().m2() - WFL().m2() + sqr(W); Energy PR = (a + sqrt(sqr(a) - WFR().m2()*sqr(W)))*0.5/W; //Create the dipole states and impact parameters. vector vl(preSampleL()); vector vr(preSampleR()); vector vb(preSampleB()); vector< vector< vector > > probs(preSampleL(), vector< vector >(preSampleR(), vector(preSampleB(), 0.0))); // Setup a number of left- and right-moving states double highYL = 0.0; for ( int il = 0; il < preSampleL(); ++il ) { DipoleStatePtr dl = WFL().generate(*this, PL); vl[il] = dl; dl->collidingEnergy(PR); highYL += dl->highestY(); } highYL /= double(preSampleL()); double highYR = 0.0; for ( int ir = 0; ir < preSampleR(); ++ir ) { DipoleStatePtr dr = WFR().generate(*this, PR); vr[ir] = dr; dr->collidingEnergy(PL); highYR += dr->highestY(); } highYR /= double(preSampleR()); // Evolve the states double y0L = -highYR; double y0R = -highYL; if ( !noFrame() ) { y0L = interactionFrame(highYL, -highYR); y0R = -y0L; } for ( int il = 0; il < preSampleL(); ++il ) { vl[il]->evolve(vl[il]->lowestY(), y0L); vl[il]->unifyColourSystems(); } for ( int ir = 0; ir < preSampleR(); ++ir ) { vr[ir]->evolve(vr[ir]->lowestY(), y0R); vr[ir]->unifyColourSystems(); } for ( int ib = 0; ib < preSampleB(); ++ib ) { ImpactParameters b = bGen().generate(); vb[ib] = b; } for ( int il = 0; il < preSampleL(); ++il ) for ( int ir = 0; ir < preSampleR(); ++ir ) for ( int ib = 0; ib < preSampleB(); ++ib ) { DipoleStatePtr dl =vl[il]; DipoleStatePtr dr =vr[ir]; ImpactParameters b = vb[ib]; double prob = 0; //Calculate interaction probability, and apply all the weights if ( eventFiller().mode() == 4 || effectivePartonMode() < 0 ) prob = xSecFn().sumf(b, *dr, *dl); else prob = xSecFn().sumf(*dr, *dl, b); probs[il][ir][ib] = prob; CrossSection weight = sqr(hbarc)*dr->weight()*dl->weight()*b.weight()*jac; //This is the contribution to the non-diffractive //cross section 1 - exp(-2(amp)^2) CrossSection x = weight*xSecFn().unitarize(2.0*prob); if ( x > xmax ) { xnmax = xmax; xmax = x; } else xnmax = max(x, xnmax); //Call the analysis (which calculates cross sections) for ( int i = 0, N = analyses.size(); i < N; ++i ) analyses[i]->analyze(*dr, *dl, b, xSecFn(), prob, weight); } // Call the analysis (which calculates cross sections) for all // systems and impact parameters. for ( int i = 0, N = analyses.size(); i < N; ++i ) analyses[i]->analyze(vr, vl, vb, xSecFn(), probs, jac); } //Write output (also from the called analyses) to log file. if ( preSamples() > 0 ) { generator()->log() << "Presampled " << preSamples() << " collisions (" << elapsed()/max(preSamples(),0) << " seconds per collisions)" << endl << "Maximum cross section: " << ouniterr(xmax, xmax-xnmax, nanobarn) << " nb." <log() << endl; } stats = XSecStat(xmax > 0.0*nanobarn? xmax: 1.0*millibarn); } void DipoleEventHandler::diffractivePresample() { //Setup before Current current(this); for_each(analyses, mem_fun(&DipoleAnalysisHandler::initialize)); CrossSection xmax = 0.0*picobarn; CrossSection xnmax = 0.0*picobarn; elapsed(); generator()->log() << endl << "Starting Diffractive DIPSY run at CoM energy " << lumiFn().maximumCMEnergy()/GeV << " GeV" << endl; Energy W = lumiFn().maximumCMEnergy(); double jac = 1.0; pair ll(1.0, 1.0); //Create the starting states from their wavefunction. if ( int ndim = lumiFn().nDim(make_pair(WFL().particle(), WFR().particle())) ) { vector r = UseRandom::rndvec(ndim); ll = lumiFn().generateLL(&(r[0]), jac); W *= exp(-0.5*(ll.first + ll.second)); } //Calculate the energy of each incoming state in this frame. Energy2 a = WFL().m2() - WFR().m2() + sqr(W); Energy PL = (a + sqrt(sqr(a) - WFL().m2()*sqr(W)))*0.5/W; a = WFR().m2() - WFL().m2() + sqr(W); Energy PR = (a + sqrt(sqr(a) - WFR().m2()*sqr(W)))*0.5/W; //Set up rapidity intervals to evolve over. double yminL = -log(PL/sqrt(abs(WFL().m2()))); double yminR = -log(PR/sqrt(abs(WFR().m2()))); double y0L = -yminR; double y0R = -yminL; if ( !noFrame() ) { y0L = interactionFrame(yminL, -yminR); y0R = -y0L; } //Pre-generate the virtual cascade, ie the ones from the //elastic side (right side by default). vector virtualCascades; for ( int i = 0, N = preSamples(); i < N; i ++ ) { DipoleStatePtr virt = WFR().generate(*this, PR); virt->collidingEnergy(PL); virt->evolve(virt->lowestY(), y0R); virtualCascades.push_back(virt); } CrossSection sigmaSD = ZERO; DipoleAnalysisHandler::CrossSection2 sigmaSD2 = ZERO; //Now run main loop over the real (excited in final state) cascades. for ( int i = 0, N = preSamples(); i < N; ++i ) { DipoleStatePtr dl = WFL().generate(*this, PL); dl->collidingEnergy(PR); dl->evolve(dl->lowestY(), y0L); ImpactParameters b = bGen().generate(); double sum = 0.0; double sumWeights = 0.0; //Loop over the pregenerated virtual elastic for ( int j = 0; j < N; j ++ ) { double amp = xSecFn().unitarize(xSecFn().sumf(*virtualCascades[j], *dl, b)); sum += amp*virtualCascades[j]->weight(); sumWeights += virtualCascades[j]->weight(); } double average = sum/sumWeights; //Take statistics on inclusive single diffractive cross section. CrossSection weight = sqr(hbarc)*dl->weight()*b.weight()*jac; CrossSection x = weight*average; sigmaSD += weight*sqr(average); sigmaSD2 += sqr(weight*sqr(average)); if ( x > xmax ) { xnmax = xmax; xmax = x; } else xnmax = max(x, xnmax); //Pass on to analysers. for ( int j = 0, M = analyses.size(); j < M; ++j ) analyses[j]->analyze(*WFR().generate(*this, PR), *dl, b, xSecFn(), average, weight); } //Output results to log file. if ( preSamples() > 0 ) { sigmaSD /= preSamples(); sigmaSD2 /= preSamples(); //Estimate error from the fluctuations. CrossSection err = sqrt((sigmaSD2 - sqr(sigmaSD))/preSamples()); generator()->log() << "Presampled " << preSamples() << " real cascades, collided with " << preSamples() << " virtual cascades (" << elapsed()/max(preSamples(),0) << " seconds per real cascade)" << endl << "Maximum cross section: " << ouniterr(xmax, xmax-xnmax, nanobarn) << " nb." <log() << endl; } stats = XSecStat(xmax > 0.0*nanobarn? xmax: 1.0*millibarn); } void DipoleEventHandler::initialize() { Current current(this); theWFL->initialize(*this); theWFR->initialize(*this); } EventPtr DipoleEventHandler::generateEvent() { //Redirect diffractive events. if ( collisionType() == 1 ) return generateDiffractiveEvent(); while ( true ) { Current current(this); //Set up energy, jacobians and wavefunctions. Energy W = lumiFn().maximumCMEnergy(); double jac = 1.0; pair ll(1.0, 1.0); if ( int ndim = lumiFn().nDim(make_pair(WFL().particle(), WFR().particle())) ) { vector r = UseRandom::rndvec(ndim); ll = lumiFn().generateLL(&(r[0]), jac); } //Find lightcone momenta. Energy2 a = WFL().m2() - WFR().m2() + sqr(W); Energy PL = (a + sqrt(sqr(a) - 4.0*WFL().m2()*sqr(W)))*0.5/W; a = WFR().m2() - WFL().m2() + sqr(W); Energy PR = (a + sqrt(sqr(a) - 4.0*WFR().m2()*sqr(W)))*0.5/W; PPair inc(WFL().particle()->produceParticle(lightCone(PL, WFL().m2()/PL)), WFR().particle()->produceParticle(lightCone(WFR().m2()/PR, PR))); LorentzRotation cmboost = lumiFn().getBoost()*LorentzRotation(0.0, 0.0, tanh(0.5*(ll.second - ll.first))); inc.first->transform(cmboost); inc.second->transform(cmboost); //Create dipole states. DipoleStatePtr dr = WFR().generate(*this, PR); DipoleStatePtr dl = WFL().generate(*this, PL); //in some settings, the states need to know about the //energy of the other state. dr->collidingEnergy(PL); dl->collidingEnergy(PR); double y0L = -dr->highestY(); double y0R = -dl->highestY(); if ( !noFrame() ) { y0L = interactionFrame(dl->highestY(), -dr->highestY()); y0R = -y0L; } dr->evolve(dr->lowestY(), y0R); dr->unifyColourSystems(); dl->evolve(dl->lowestY(), y0L); dl->unifyColourSystems(); // This generates the impact parameter depending on the position //of the partons. Intention was to generate high-pt events more //often by selecting a b such that two partons would end up //very close to each other more often. Should work in theory, but //didn't make as big difference as hoped, maybe due to too many //of the high pTs coming from the cascade. // vector > points1 = dl->points(); // vector > points2 = dr->points(); // ImpactParameters b = bGen().generateDynamic(points1, points2); //Standard impact parameter generation. ImpactParameters b = bGen().generate(); inc.first->setVertex (LorentzPoint(hbarc*b.bVec().x()/2, hbarc*b.bVec().y()/2, ZERO, ZERO)); inc.second->setVertex (LorentzPoint(-hbarc*b.bVec().x()/2, -hbarc*b.bVec().y()/2, ZERO, ZERO)); currentEvent(new_ptr(Event(inc, this, generator()->runName(), generator()->currentEventNumber(), 1.0))); currentCollision(new_ptr(Collision(inc, currentEvent(), this))); if ( currentEvent() ) currentEvent()->addCollision(currentCollision()); currentStep(new_ptr(Step(currentCollision()))); currentCollision()->addStep(currentStep()); double genweight = sqr(hbarc)*dr->weight()*dl->weight()*b.weight()*jac/ stats.maxXSec(); //Pass to filler. This is where the final state is decided. double prob = eventFiller().fill(*currentStep(), *this, inc, *dl, *dr, b); double weight = prob*genweight; stats.select(weight); currentEvent()->weight(weight); if ( weight <= 0.0 ) continue; stats.accept(); try { initGroups(); continueCollision(); return currentEvent(); } catch (Veto) { stats.reject(weight); } catch (Stop) { break; } catch (Exception &) { stats.reject(weight); throw; } } return currentEvent(); } EventPtr DipoleEventHandler::generateDiffractiveEvent() { //Very similar to generateEvent. while ( true ) { //Same setup as in the non-diffractive case. Current current(this); Energy W = lumiFn().maximumCMEnergy(); double jac = 1.0; pair ll(1.0, 1.0); if ( int ndim = lumiFn().nDim(make_pair(WFL().particle(), WFR().particle())) ) { vector r = UseRandom::rndvec(ndim); ll = lumiFn().generateLL(&(r[0]), jac); } Energy2 a = WFL().m2() - WFR().m2() + sqr(W); Energy PL = (a + sqrt(sqr(a) - 4.0*WFL().m2()*sqr(W)))*0.5/W; a = WFR().m2() - WFL().m2() + sqr(W); Energy PR = (a + sqrt(sqr(a) - 4.0*WFR().m2()*sqr(W)))*0.5/W; PPair inc(WFL().particle()->produceParticle(lightCone(PL, WFL().m2()/PL)), WFR().particle()->produceParticle(lightCone(WFL().m2()/PR, PR))); LorentzRotation cmboost = lumiFn().getBoost()*LorentzRotation(0.0, 0.0, tanh(0.5*(ll.second - ll.first))); inc.first->transform(cmboost); inc.second->transform(cmboost); //create real excited valence. Evolution is done in diffFill. DipoleStatePtr dr = WFL().generate(*this, PL); //create elastic DipoleStatePtr de = WFR().generate(*this, PR); ImpactParameters b = bGen().generate(); inc.first->setVertex (LorentzPoint(hbarc*b.bVec().x()/2, hbarc*b.bVec().y()/2, ZERO, ZERO)); inc.second->setVertex (LorentzPoint(-hbarc*b.bVec().x()/2, -hbarc*b.bVec().y()/2, ZERO, ZERO)); currentEvent(new_ptr(Event(inc, this, generator()->runName(), generator()->currentEventNumber(), 1.0))); currentCollision(new_ptr(Collision(inc, currentEvent(), this))); if ( currentEvent() ) currentEvent()->addCollision(currentCollision()); currentStep(new_ptr(Step(currentCollision()))); currentCollision()->addStep(currentStep()); double genweight = sqr(hbarc)*dr->weight()*de->weight()*b.weight()*jac/ stats.maxXSec(); //Call filler, which will be redirected to diffractive version. double prob = eventFiller().fill(*currentStep(), *this, inc, *dr, *de, b); double weight = prob*genweight; if ( weight <= 0.0 ) continue; if ( isnan(weight) ) { continue; } stats.select(weight); currentEvent()->weight(weight); stats.accept(); try { initGroups(); continueCollision(); return currentEvent(); } catch (Veto) { stats.reject(weight); } catch (Stop) { break; } catch (Exception &) { stats.reject(weight); throw; } } return currentEvent(); } CrossSection DipoleEventHandler::integratedXSec() const { return stats.xSec(); } CrossSection DipoleEventHandler::integratedXSecErr() const { return stats.xSecErr(); } CrossSection DipoleEventHandler::maxXSec() const { return stats.maxXSec(); } CrossSection DipoleEventHandler::histogramScale() const { return stats.xSec()/stats.sumWeights(); } void DipoleEventHandler::statistics(ostream & os) const { string line = "=======================================" "=======================================\n"; if ( stats.accepted() <= 0 ) { os << line << "No events generated by event handler '" << name() << "'." << endl; return; } os << line << "Statistics for event handler \'" << name() << "\':\n" << " " << "generated number of Cross-section\n" << " " << " events attempts (nb)\n"; os << line << "Total:" << setw(42) << stats.accepted() << setw(13) << stats.attempts() << setw(17) << ouniterr(stats.xSec(), stats.xSecErr(), nanobarn) << endl << line; } -void DipoleEventHandler::doinit() throw(InitException) { +void DipoleEventHandler::doinit() { Current current(this); EventHandler::doinit(); } void DipoleEventHandler::dofinish() { generator()->log() << endl << "Ending DIPSY run at CoM energy " << lumiFn().maximumCMEnergy()/GeV << " GeV" << endl; theEventFiller->finish(); EventHandler::dofinish(); CPUClock::dump(generator()->log()); } void DipoleEventHandler::doinitrun() { Current current(this); EventHandler::doinitrun(); theNErr = 0; for_each(analyses, mem_fun(&DipoleAnalysisHandler::initrun)); if ( theSwinger ) theSwinger->initrun(); theEmitter->initrun(); theBGen->initrun(); theXSecFn->initrun(); theEventFiller->initrun(); theWFL->initrun(); theWFR->initrun(); if ( externalAlphaS() ) externalAlphaS()->initrun(); presample(); // Fix up a dummy XComb object Energy emax = lumiFn().maximumCMEnergy(); cuts()->initialize(sqr(emax), 0.0); cPDPair incoming = make_pair(WFL().particle(), WFR().particle()); PartonPairVec bins = partonExtractor()->getPartons(emax, incoming, *cuts()); theLastXComb = new_ptr(XComb(emax, incoming, this, partonExtractor(), tCascHdlPtr(), bins[0], cuts())); theLastXComb->lastSHat(sqr(emax)); theLastXComb->lastY(0.0); theLastXComb->lastP1P2(make_pair(0.0, 0.0)); theLastXComb->lastL1L2(make_pair(0.0, 0.0)); theLastXComb->lastX1X2(make_pair(1.0, 1.0)); theLastXComb->lastScale(sqr(emax)); theLastXComb->lastAlphaS(1.0); theLastXComb->lastAlphaEM(1.0/137.0); partonExtractor()->select(theLastXComb); } -void DipoleEventHandler::rebind(const TranslationMap & trans) throw(RebindException) { +void DipoleEventHandler::rebind(const TranslationMap & trans) { // dummy = trans.translate(dummy); EventHandler::rebind(trans); } IVector DipoleEventHandler::getReferences() { IVector ret = EventHandler::getReferences(); // ret.push_back(dummy); return ret; } double DipoleEventHandler::alphaS(Energy mu) const { double alps = 0.0; mu = max(mu, m0()); if ( fixedAlphaS() > 0.0 ) alps = fixedAlphaS(); else if ( LambdaQCD() > 0.0*GeV && LambdaQCD() < m0() ) alps = 6.0*Constants::pi/((33.0 - 2.0*nF())*log(mu/LambdaQCD())); else if ( externalAlphaS() ) alps = externalAlphaS()->value(sqr(mu), SM()); else alps = SM().alphaS(sqr(mu)); if ( fixedAlphaS() < 0.0 ) { alps = min(alps, -fixedAlphaS()); if ( alps < 0.0 ) alps = -fixedAlphaS(); } return alps; } double DipoleEventHandler::interactionFrame(double ymin, double ymax) const { double yframe = yFrame(); if ( yFrame() < -1.0 && yFrame() >= -1.5 ) { double dum = -(yFrame() + 1.0); yframe = UseRandom::rnd(dum, 1.0 - dum); } double y0 = ymin + yframe*(ymax - ymin); if ( y0 > ymax ) y0 = max(ymin, ymax + (1.0 - yframe)); else if ( y0 < ymin ) y0 = min(ymax, ymin + yframe); return y0; } void DipoleEventHandler::persistentOutput(PersistentOStream & os) const { os << theNColours << ounit(theRMax, InvGeV) << ounit(theM0, GeV) << thePTScale << ounit(theBaryonSize, InvGeV) << ounit(theCoherenceRange, InvGeV) << theEffectivePartonMode << theCollisionType << doShowHistory << ounit(theLambdaQCD, GeV) << theNF << theFixedAlphaS << theExternalAlphaS << theWFR << theWFL << theBGen << theYFrame << theNoFrame << theFudgeME << theFudgeFactorME << thePreSamples << thePreSampleL << thePreSampleR << thePreSampleB << theXSecFn << theEmitter << theSwinger << theEventFiller << analyses << stats; } void DipoleEventHandler::persistentInput(PersistentIStream & is, int) { is >> theNColours >> iunit(theRMax, InvGeV) >> iunit(theM0, GeV) >> thePTScale >> iunit(theBaryonSize, InvGeV) >> iunit(theCoherenceRange, InvGeV) >> theEffectivePartonMode >> theCollisionType >> doShowHistory >> iunit(theLambdaQCD, GeV) >> theNF >> theFixedAlphaS >> theExternalAlphaS >> theWFR >> theWFL >> theBGen >> theYFrame >> theNoFrame >> theFudgeME >> theFudgeFactorME >> thePreSamples >> thePreSampleL >> thePreSampleR >> thePreSampleB >> theXSecFn >> theEmitter >> theSwinger >> theEventFiller >> analyses >> stats; } // Static variable needed for the type description system in ThePEG. #include "ThePEG/Utilities/DescribeClass.h" DescribeClass describeDIPSYDipoleEventHandler("DIPSY::DipoleEventHandler", "libAriadne5.so libDIPSY.so"); void DipoleEventHandler::Init() { static ClassDocumentation documentation ("The DipoleEventHandler is a special EventHandler capable of generating " "minimum-bias events using the Lund version of the Mueller dipole model."); static Parameter interfaceNColours ("NColours", "The number of different colour indices in the swing mechanism. Should be " "\\f$N_c^2\\f$ but can be varied to investigate swing effects.", &DipoleEventHandler::theNColours, 9, 3, 0, true, false, Interface::lowerlim); static Parameter interfaceRMax ("RMax", "The general hadronic size in units of inverse GeV. This parameter is overridden " "if M0 is larger than zero, in which case " "PTScale/M0 is used instead.", &DipoleEventHandler::theRMax, InvGeV, 3.5*InvGeV, 0.0*InvGeV, 0*InvGeV, true, false, Interface::lowerlim); static Parameter interfaceM0 ("M0", "The non-perturbative scale in GeV. If set to zero or less, " "PTScale/RMax will be used instead.", &DipoleEventHandler::theM0, GeV, 0.0*GeV, 0.0*GeV, 0.0*GeV, true, false, Interface::lowerlim); static Parameter interfacePTScale ("PTScale", "The scale used to relate impactparameter distances and transverse " "momenta. If negative, it is instead taken from the assigned " "Emitter::PTScale.", &DipoleEventHandler::thePTScale, 2.0, 0, 0, true, false, Interface::nolimits); static Parameter interfaceCoherenceRange ("CoherenceRange", "The maximum range at which partons are allowed to emit coherently." "This is also used as maximum range in the DGLAP suppression", &DipoleEventHandler::theCoherenceRange, InvGeV, 0.5*InvGeV, 0.0*InvGeV, 0*InvGeV, true, false, Interface::lowerlim); static Switch interfaceEffectivePartonMode ("EffectivePartonMode", "How the partons are grouped inteo effective partons.", &DipoleEventHandler::theEffectivePartonMode, 0, true, false); static SwitchOption interfaceEffectivePartonModeColours (interfaceEffectivePartonMode, "Colours", "Groups with colour neighbours. Makes more sence since the " "colour flow determines how the emissions are made, but the " "swing makes this mode not always group up recoiling partons, " "which can mess up availible phase space and ordering. " "This is default.", 0); static SwitchOption interfaceEffectivePartonModeFastColours (interfaceEffectivePartonMode, "FastColours", "Groups with colour neighbours as for the \"Colour\" option, " "but speed up the generation by caching different ranges for " "the same parton.", 2); static SwitchOption interfaceEffectivePartonModeFastColours2 (interfaceEffectivePartonMode, "FastColours2", "Groups with colour neighbours as for the \"FastColour\" option, " "but speed up the generation by caching different ranges for " "the same parton.", 3); static SwitchOption interfaceEffectivePartonModeRelatives (interfaceEffectivePartonMode, "Relatives", "Groups with parents and childs. Always pairs up with the " "recoiling pt, and should get the phase space and ordering " "correct, but makes the emissions depend on the history" ", not only current state.", 1); static SwitchOption interfaceEffectivePartonModeShadows (interfaceEffectivePartonMode, "Shadows", "Don't use Effective partons, use shadow partons instead.", -1); static SwitchOption interfaceEffectivePartonModeNewShadows (interfaceEffectivePartonMode, "NewShadows", "Don't use Effective partons, use shadow partons instead.", -2); static Switch interfaceCollisionType ("CollisionType", "What type of collison.", &DipoleEventHandler::theCollisionType, 0, true, false); static SwitchOption interfaceCollisionTypeNonDiffractive (interfaceCollisionType, "NonDiffractive", "Should be self explanatory. :P", 0); static SwitchOption interfaceTypeSingleDiffractive (interfaceCollisionType, "SingleDiffractive", "Should be self explanatory. :P", 1); - static Parameter interfaceShowHistory + static Switch interfaceShowHistory ("ShowHistory", "If the history of every event should be studied manually." "Note that only final state events get studied, not the presamples.", - &DipoleEventHandler::doShowHistory, false, false, false, - true, false, Interface::lowerlim); + &DipoleEventHandler::doShowHistory, false, true, false); + static SwitchOption interfaceShowHistoryNo + (interfaceShowHistory, + "No", + "Do not study history manually.", + false); + static SwitchOption interfaceShowHistoryYes + (interfaceShowHistory, + "Yes", + "Study history manually.", + true); + static SwitchOption interfaceShowHistoryNo0 + (interfaceShowHistory, + "0", + "Do not study history manually.", + false); + static SwitchOption interfaceShowHistoryYes1 + (interfaceShowHistory, + "1", + "Study history manually.", + true); static Parameter interfaceLambdaQCD ("LambdaQCD", "The value of \\f$\\Lambda_{QCD}\\f$ to be used in the running coupling. " "If zero, the AlphaS object will be used for the " "coupling instead.", &DipoleEventHandler::theLambdaQCD, GeV, 0.22*GeV, 0.0*GeV, 0*GeV, true, false, Interface::lowerlim); static Parameter interfaceFixedAlphaS ("FixedAlphaS", "The value of the constant coupling. If zero, a running coupling is " "assumed.", &DipoleEventHandler::theFixedAlphaS, 0.0, 0.0, 0, true, false, Interface::nolimits); static Reference interfaceExternalAlphaS ("ExternalAlphaS", "An external \\f$\\alpha_S\\f$ object to be used if " "LambdaQCD is zero. If null the object " "specified in the overall StandardModel object will be used insted.", &DipoleEventHandler::theExternalAlphaS, true, false, true, true, false); static Parameter interfaceNF ("NF", "The number of flavours to be used in the running coupling. Not active " "if an external running coupling (ExternalAlphaS " "is used.", &DipoleEventHandler::theNF, 3, 1, 0, true, false, Interface::lowerlim); static Reference interfaceWFR ("WFR", "The wave function of the incoming particle along the positive z-axis.", &DipoleEventHandler::theWFR, true, false, true, false, false); static Reference interfaceWFL ("WFL", "The wave function of the incoming particle along the negative z-axis.", &DipoleEventHandler::theWFL, true, false, true, false, false); static Parameter interfaceYFrame ("YFrametest", "Indicate in which frame the dipole systems should collide. A value of " "0.5 means that both systems will be evolved an equal rapidity distance. " "0.0 (1.0) means that the right(left)-moving system will not be evolved " "at all while the left(right)-moving system will be evolved as much as " "possible. A value larger than 1.0 (less than 0.0) means the right-(left-)moving " "system will be evolved a fixed rapidity interval YFrametest - 1 (-YFrametest)", &DipoleEventHandler::theYFrame, 0.5, 0.0, 1.0, true, false, Interface::nolimits); static Switch interfaceNoFrame ("Frame", "The choice of stategy for choosing interactions frame.", &DipoleEventHandler::theNoFrame, 0, true, false); static SwitchOption interfaceNoFrameFixedY (interfaceNoFrame, "FixedY", "Choose a fixed rapidity given by YFrametest.", 0); static SwitchOption interfaceNoFrameNoFrame (interfaceNoFrame, "NoFrame", "Choose different frames for each dipole-dipole interactions.", 1); static Switch interfaceFudgeME ("FudgeME", "Indicate whether a fudge factor should be included to tame the high-pt tail " "according to an approximate matrix element correction.", &DipoleEventHandler::theFudgeME, 0, true, false); static SwitchOption interfaceFudgeMEFudge (interfaceFudgeME, "Fudge", "Include fudge factor", 1); static SwitchOption interfaceFudgeMEFudgeC (interfaceFudgeME, "Fudge", "Include fudge factor and make cross section dependent on the colour " "indices of the colliding dipoles", 2); static SwitchOption interfaceFudgeMENoFudge (interfaceFudgeME, "NoFudge", "Do not include fudge factor", 0); static Parameter interfaceFudgeFactorME ("FudgeFactorME", "Extra factor to be applied for high-pt scattering in interactions.", &DipoleEventHandler::theFudgeFactorME, 1.0, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfacePreSamples ("PreSamples", "The number of collisions to analyze in the presampling.", &DipoleEventHandler::thePreSamples, 1000, 0, 0, true, false, Interface::lowerlim); static Parameter interfacePreSampleL ("PreSampleL", "The number of left-moving systems to generate for each presample.", &DipoleEventHandler::thePreSampleL, 1, 1, 0, true, false, Interface::lowerlim); static Parameter interfacePreSampleR ("PreSampleR", "The number of right-moving systems to generate for each presample.", &DipoleEventHandler::thePreSampleR, 1, 1, 0, true, false, Interface::lowerlim); static Parameter interfacePreSampleB ("PreSampleB", "The number ofimpact parameters to generate for each presample.", &DipoleEventHandler::thePreSampleB, 1, 1, 0, true, false, Interface::lowerlim); static Reference interfaceXSecFn ("XSecFn", "The object responsible for calculating the cross section for two " "colliding dipole systems.", &DipoleEventHandler::theXSecFn, true, false, true, false, false); static Reference interfaceBGen ("BGen", "The object responsible for generating the impact parameters.", &DipoleEventHandler::theBGen, true, false, true, false, false); static Reference interfaceEmitter ("Emitter", "The object responsible for generating and performing dipole emissions " "of gluons.", &DipoleEventHandler::theEmitter, true, false, true, false, false); static Reference interfaceSwinger ("Swinger", "The object responsible for generating and performing dipole swings.", &DipoleEventHandler::theSwinger, true, false, true, true, false); static Reference interfaceEventFiller ("EventFiller", "The object responsible for filling an event with final state gluons.", &DipoleEventHandler::theEventFiller, true, false, true, false, false); static RefVector interfaceAnalysisHandlers ("AnalysisHandlers", "A list of analysis to be performed in the presample phase.", &DipoleEventHandler::analyses, -1, true, false, true, false, false); static Parameter interfaceBaryonSize ("BaryonSize", "The typical size of a baryon to be used by wave functions not " "defining their own. If zero, RMax will " "be used instead.", &DipoleEventHandler::theBaryonSize, InvGeV, 0.0*InvGeV, 0.0*InvGeV, 0*InvGeV, true, false, Interface::lowerlim); } diff --git a/DIPSY/DipoleEventHandler.h b/DIPSY/DipoleEventHandler.h --- a/DIPSY/DipoleEventHandler.h +++ b/DIPSY/DipoleEventHandler.h @@ -1,674 +1,674 @@ // -*- C++ -*- #ifndef DIPSY_DipoleEventHandler_H #define DIPSY_DipoleEventHandler_H // // This is the declaration of the DipoleEventHandler class. // #include "ThePEG/Handlers/EventHandler.h" #include "DipoleEventHandler.fh" #include "WaveFunction.h" #include "DipoleXSec.h" #include "Emitter.h" #include "Swinger.h" #include "EventFiller.h" // #include "DiffractiveEventFiller.h" #include "ImpactParameterGenerator.h" #include "DipoleAnalysisHandler.h" #include "ThePEG/StandardModel/AlphaSBase.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Utilities/XSecStat.h" namespace DIPSY { using namespace ThePEG; /** * Here is the documentation of the DipoleEventHandler class. * * @see \ref DipoleEventHandlerInterfaces "The interfaces" * defined for DipoleEventHandler. */ class DipoleEventHandler: public EventHandler { public: /** Declare a pointer to an AlphaSBase object. */ typedef Ptr::pointer ASPtr; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ DipoleEventHandler(); /** * The destructor. */ virtual ~DipoleEventHandler(); //@} public: /** * Initialize this event handler and all related objects needed to * generate events. */ virtual void initialize(); /** * Pre-sample the cross section before generating events. * This does inclusive cross section for non-diffractive collisions. * Diffractive inclusive cross sections are redirected. */ void presample(); /** * Pre-sample the single diffractive cross section before * generating events. This requires a different method, as it * needs a double loop over events. */ void diffractivePresample(); /** * Generate an event. */ virtual EventPtr generateEvent(); /** * Generate a diffractive event. */ virtual EventPtr generateDiffractiveEvent(); /** * Write out statistics. */ virtual void statistics(ostream &) const; /** * The total integrated cross section of the processes generated in * this run. * @return 0 if no integrated cross section could be estimated. */ virtual CrossSection integratedXSec() const; /** * The error total integrated cross section of the processes * generated in this run. * @return 0 if no integrated cross section could be estimated. */ virtual CrossSection integratedXSecErr() const; /** * The overestimated cross section ised in the generation. */ CrossSection maxXSec() const; /** * Histogram scale. A histogram bin which has been filled with the * weights associated with the Event objects should be scaled by * this factor to give the correct cross section. */ virtual CrossSection histogramScale() const; /** * Return the running coupling for the given scale. */ double alphaS(Energy mu) const; /** * Return the running coupling for the given size. */ inline double alphaSr(InvEnergy r) const { return alphaS(pTScale()/r); } /** @name Simple access functions. */ //@{ /** * The number of different colour indices. */ inline int nColours() const { return theNColours; } /** * The general hadronic size. */ inline InvEnergy rMax() const { return theM0 <= ZERO? theRMax: pTScale()/theM0; } /** * The non-perturbative scale. */ inline Energy m0() const { return theM0 > ZERO? theM0: pTScale()/theRMax; } /** * Get the typical size of a baryon to be used by wave functions not * defining their own. */ inline InvEnergy baryonSize() const { return theBaryonSize > ZERO? theBaryonSize: rMax(); } /** * The maximum range at which coherent emissions are allowed. */ inline InvEnergy coherenceRange() const { return theCoherenceRange; } /** * Return the effective parton mode. */ inline int effectivePartonMode() const { return theEffectivePartonMode; } /** * Return the collision type. */ inline int collisionType() const { return theCollisionType; } /** * The value of \f$\Lambda_{QCD}\f$ to be used in the running coupling. */ inline Energy LambdaQCD() const { return theLambdaQCD; } /** * The number of flavours to be used in the running coupling. */ inline int nF() const { return theNF; } /** * The value of the constant coupling. If zero, a running coupling is assumed. */ inline double fixedAlphaS() const { return theFixedAlphaS; } /** * An external \f$\alpha_S\f$ object to be used if LambdaQCD() is zero. */ inline ASPtr externalAlphaS() const { return theExternalAlphaS; } /** * Alpha bar = alphas*Nc/pi */ inline double alphaBarr(InvEnergy r) const { return alphaSr(r)*3.0/M_PI; } /** * Alpha bar = alphas*Nc/pi */ inline double alphaBar(Energy mu) const { return alphaS(mu)*3.0/M_PI; } /** * Get the wave function of the incoming particle along the positive z-axis. */ inline WaveFunction & WFR() const { return *theWFR; } /** * Get the wave function of the incoming particle along the negative z-axis. */ inline WaveFunction & WFL() const { return *theWFL; } /** * Get the object responsible for generating the impact parameters. */ inline const ImpactParameterGenerator & bGen() const { return *theBGen; } /** * Indicate whether a fudge factor should be included to tame the * high-pt tail according to an approximate matrix element * correction. */ inline int fudgeME() const { return theFudgeME; } /** * Indicate whether an additional fudge factor should be included to tame the * high-pt tail in the interactions. */ inline double fudgeFactorME() const { return theFudgeFactorME; } /** * Indicate in which frame the dipole systems should collide. */ inline double yFrame() const { return theYFrame; } /** * Options related to using the full rapidity range for both * cascades and decide interaction fram on a dipole-dipole basis. */ inline int noFrame() const { return theNoFrame; } /** * Return the rapidity to use for the interaction frame. */ double interactionFrame(double ymin, double ymax) const; /** * Get the number of collisions to analyze in the presampling. */ inline int preSamples() const { return thePreSamples; } /** * The number of left-moving systems to generate for each presample. */ inline int preSampleL() const { return thePreSampleL; } /** * The number of right-moving systems to generate for each presample. */ inline int preSampleR() const { return thePreSampleR; } /** * The number of impact parameters to generate for each presample. */ inline int preSampleB() const { return thePreSampleB; } /** * Get the object responsible for calculating the cross section for * two colliding dipole systems. */ inline const DipoleXSec & xSecFn() const { return *theXSecFn; } /** * Get the object responsible for generating and performing dipole * emissions of gluons. */ inline const Emitter & emitter() const { return *theEmitter; } /** * Get the scale used to convert between impact parameters and * transverse momenta. */ double pTScale() const { return thePTScale > 0? thePTScale: emitter().pTScale(); } /** * Set the object responsible for generating and performing dipole * emissions of gluons. * Added by CF to access from emitter. */ inline void emitter(EmitterPtr em) { theEmitter = em; } /** * Set the object responsible for generating and performing dipole * swings. * Added by CF to access from emitter. */ inline void swinger(SwingerPtr sw) { theSwinger = sw; } /** * Get the object responsible for generating and performing dipole swings. */ inline const Swinger & swinger() const { return *theSwinger; } /** * Get the object responsible for generating and performing dipole swings. */ inline tSwingerPtr swingPtr() const { return theSwinger; } /** * Get the object responsible for filling an event with final state gluons. */ inline const EventFiller & eventFiller() const { return *theEventFiller; } // /** // * Get the object responsible for filling an event with final state gluons. // */ // inline const DiffractiveEventFiller & diffractiveEventFiller() const { // return *theDiffractiveEventFiller; // }; /** * adds an error to the counter **/ inline void err() const { theNErr++; }; /** * returns teh number of errors so far. **/ inline const long nErr() const { return theNErr; }; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The number of different colour indices. */ int theNColours; /** * The general hadronic size. */ InvEnergy theRMax; /** * The Non-perturbative scale correponding to a small gluon mass. If * zero or less it is instead given by thePTScale/theRMax. */ Energy theM0; /** * The scale used to relate impactparameter distances and transverse * momenta. */ double thePTScale; /** * The typical size of a baryon to be used by wave functions not * defining their own. If zero, theRMax or theM0 will be used instead. */ InvEnergy theBaryonSize; /** * The maximum range at which partons can emit coherently as effective partons. */ InvEnergy theCoherenceRange; /** * The way the partons are grouped into effective partons. */ int theEffectivePartonMode; /** * The type of collison. 0: non diffractive, 1: single diffractive */ int theCollisionType; /** * if the history of every event should be studied manually. */ bool doShowHistory; /** * The value of \f$\Lambda_{QCD}\f$ to be used in the running coupling. */ Energy theLambdaQCD; /** * The number of flavours to be used in the running coupling. */ int theNF; /** * The value of the constant coupling. If zero, a running coupling is assumed. */ double theFixedAlphaS; /** * An external \f$\alpha_S\f$ object to be used if LambdaQCD() is zero. */ ASPtr theExternalAlphaS; /** * The wave function of the incoming particle along the positive z-axis. */ WaveFunctionPtr theWFR; /** * The wave function of the incoming particle along the negative z-axis. */ WaveFunctionPtr theWFL; /** * The object responsible for generating the impact parameters. */ ImpactParameterGeneratorPtr theBGen; /** * Indicate in which frame the dipole systems should collide. */ double theYFrame; /** * Options related to using the full rapidity range for both * cascades and decide interaction fram on a dipole-dipole basis. */ int theNoFrame; /** * Indicate whether a fudge factor should be included to tame the * high-pt tail according to an approximate matrix element correction, * and, if so, should the dipole colours be taken into account. */ int theFudgeME; /** * Indicate whether an extra fudge factor should be included to tame * the high-pt tail in the interactions according to an approximate * matrix element correction. */ double theFudgeFactorME; /** * The number of collisions to analyze in the presampling. */ int thePreSamples; /** * The number of left-moving systems generated for each presample. */ int thePreSampleL; /** * The number of right-moving systems generated for each presample. */ int thePreSampleR; /** * The number of impact parameters generated for each presample. */ int thePreSampleB; /** * The object responsible for calculating the cross section for two * colliding dipole systems. */ DipoleXSecPtr theXSecFn; /** * The object responsible for generating and performing dipole * emissions of gluons. */ EmitterPtr theEmitter; /** * The object responsible for generating and performing dipole swings. */ SwingerPtr theSwinger; /** * The object responsible for filling an event with final state gluons. */ EventFillerPtr theEventFiller; // /** // * The object responsible for filling an event with diffractive final state gluons. // */ // DiffractiveEventFillerPtr theDiffractiveEventFiller; /** * A list of analysis objects to be applied in the presample phase. */ vector analyses; /** * Collect statistics. */ XSecStat stats; /** * The number of error messages. **/ mutable long theNErr; protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ - virtual void doinit() throw(InitException); + virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ virtual void dofinish(); /** * Rebind pointer to other Interfaced objects. Called in the setup phase * after all objects used in an EventGenerator has been cloned so that * the pointers will refer to the cloned objects afterwards. * @param trans a TranslationMap relating the original objects to * their respective clones. * @throws RebindException if no cloned object was found for a given * pointer. */ - virtual void rebind(const TranslationMap & trans) throw(RebindException); + virtual void rebind(const TranslationMap & trans); /** * Return a vector of all pointers to Interfaced objects used in this * object. * @return a vector of pointers. */ virtual IVector getReferences(); //@} public: /** Return the elapsed number of seconds since lat call. */ static double elapsed(); private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ DipoleEventHandler & operator=(const DipoleEventHandler &); }; } #endif /* DIPSY_DipoleEventHandler_H */ diff --git a/DIPSY/ElasticXSecAnalysis.cc b/DIPSY/ElasticXSecAnalysis.cc --- a/DIPSY/ElasticXSecAnalysis.cc +++ b/DIPSY/ElasticXSecAnalysis.cc @@ -1,213 +1,213 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the ElasticXSecAnalysis class. // #include "ElasticXSecAnalysis.h" #include "DipoleXSec.h" #include "DipoleState.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "gsl/gsl_sf_bessel.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace DIPSY; ElasticXSecAnalysis::ElasticXSecAnalysis(): nb(100), db(0.1*InvGeV), nq(200), dq(0.05*GeV) {} ElasticXSecAnalysis::~ElasticXSecAnalysis() {} void ElasticXSecAnalysis::initialize() { generator()->histogramFactory()->initrun(); generator()->histogramFactory()->registerClient(this); sumTw = vector(nb + 1, 0.0*picobarn); sumT2w = vector(nb + 1, 0.0*picobarn); sumT4w = vector(nb + 1, 0.0*picobarn); sumElAw = vector(nb + 1, 0.0*picobarn); sumElA2w = vector(nb + 1, 0.0*picobarn); sumw = vector(nb + 1, 0.0*picobarn); sumElw = vector(nb + 1, 0.0*picobarn); sumn = vector(nb + 1, 0); bmap.clear(); sumDEw = vector(nq + 1, 0.0*picobarn); sumDE2w = vector(nq + 1, 0.0*picobarn); } void ElasticXSecAnalysis:: analyze(const DipoleState & dl, const DipoleState & dr, const ImpactParameters & b, const DipoleXSec & xsec, double fsum, CrossSection weight) { int ib = min(nb, int(b.bVec().pt()/db)); sumTw[ib] += xsec.unitarize(fsum)*weight; sumT2w[ib] += sqr(xsec.unitarize(fsum))*weight; sumT4w[ib] += sqr(sqr(xsec.unitarize(fsum)))*weight; sumElAw[ib] += xsec.unitarize(fsum)*weight; sumElA2w[ib] += sqr(xsec.unitarize(fsum))*dl.weight()*dr.weight()*weight; if (dl.weight()*dr.weight() != 0.0 ) sumElw[ib] += weight/(dl.weight()*dr.weight()); sumw[ib] += weight; for (int iq = 0; iq < nq; iq++) { Energy q = iq*dq; double ampb = xsec.unitarize(fsum); double ampq = ampb*gsl_sf_bessel_J0(b.bVec().pt()*q); sumDEw[iq] += ampq*weight; sumDE2w[iq] += sqr(ampq)*weight; } CrossSection bw = sqr(hbarc)*b.weight(); double x = xsec.unitarize(fsum)*weight/bw; ++sumn[ib]; bmap[b.bVec().pt()] = make_pair(x, bw); } void ElasticXSecAnalysis::finalize(long neve) { if ( neve <= 0 ) return; CrossSection elXsec = 0.0*picobarn; CrossSection diffXsec = 0.0*picobarn; CrossSection totXsec = 0.0*picobarn; CrossSection2 totErrSqr = 0.0*sqr(picobarn); CrossSection2 diffErrSqr = 0.0*sqr(picobarn); CrossSection2 elErrSqr = 0.0*sqr(picobarn); CrossSection totalWeight = 0.0*picobarn; if ( ThePEG_DEBUG_LEVEL ) generator()->log() << setw(20) << name() + " -----" << " Debug output:" << endl; for ( int ib = 0; ib <= nb; ++ib ) { if ( sumw[ib] == ZERO ) continue; double avT = sumTw[ib]/sumw[ib]; double avT2 = sumT2w[ib]/sumw[ib]; double avT4 = sumT4w[ib]/sumw[ib]; double errT = sqrt(abs(avT2 - sqr(avT))/sumn[ib]); if ( sumn[ib] == 1 ) errT = avT; double errT2 = sqrt(abs(avT4 - sqr(avT2))/sumn[ib]); if ( sumn[ib] == 1 ) errT2 = avT2; if ( ThePEG_DEBUG_LEVEL ) generator()->log() << setw(25) << "b: " << ib*db*GeV << ", avT: " << avT << endl; double avElA = sumElAw[ib]/sumElw[ib]; double avElA2 = sumElA2w[ib]/sumElw[ib]; double errElA = sqrt(abs(avElA2 - sqr(avElA))/sumn[ib]); double errElA2 = 2.0*errElA*avElA; if ( sumn[ib] == 1 ) errElA = sqr(avElA); elXsec += sumElw[ib]*sqr(avElA); elErrSqr += sqr(sumElw[ib]*errElA2); diffXsec += sumw[ib]*avT2; diffErrSqr += sqr(sumw[ib]*errT2); totXsec += sumw[ib]*2.0*avT; totErrSqr += sqr(2.0*sumw[ib]*errT); totalWeight += sumw[ib]; } if ( ThePEG_DEBUG_LEVEL ) generator()->log() << setw(20) << "----- " + name() << endl;; CrossSection toterr = sqrt(totErrSqr)/double(neve); CrossSection differr = sqrt(diffErrSqr)/double(neve); CrossSection elerr = sqrt(elErrSqr)/double(neve); CrossSection diffexerr = sqrt(sqr(differr) + sqr(elerr)); CrossSection inelexerr = sqrt(sqr(differr) + sqr(toterr)); elXsec /= double(neve); diffXsec /= double(neve); totXsec /= double(neve); generator()->log().setf(ios::left, ios::adjustfield); generator()->log() << setw(50) << name() + ": Elastic cross section:" << ouniterr(elXsec, elerr, nanobarn) << " nb." << endl << setw(50) << name() + ": Crosscheck totxsec:" << ouniterr(totXsec, toterr, nanobarn) << " nb." << endl << setw(50) << name() + ": Diffractive cross section:" << ouniterr(diffXsec, differr, nanobarn) << " nb." << endl << setw(50) << name() + ": Diffractive excitation cross section:" << ouniterr(diffXsec - elXsec, diffexerr, nanobarn) << " nb." << endl << setw(50) << name() + ": Non-diffractive inelastic cross section:" << ouniterr(totXsec - diffXsec, inelexerr, nanobarn) << " nb." << endl; dSigmadq = generator()->histogramFactory()->createHistogram1D ("dSigmadq",nq,-dq/GeV,(nq-0.5)*dq/GeV); for (int iq = 0; iq < nq; iq++) { Energy q = iq*dq; CrossSection Aq = sumDEw[iq]/double(neve); //this exta factor 1/2pi comes from fourier transform //and how the MC weights are for \int d^2b rather than \int db*b that //should go with the bessel funciton - Qty<3,0,0> sigmaq = q/hbarc*sqr(Aq)/(2.0*Constants::pi); + auto sigmaq = q/hbarc*sqr(Aq)/(2.0*Constants::pi); dSigmadq->fill(q/GeV, sigmaq/nanobarn*GeV/hbarc); } } IBPtr ElasticXSecAnalysis::clone() const { return new_ptr(*this); } IBPtr ElasticXSecAnalysis::fullclone() const { return new_ptr(*this); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void ElasticXSecAnalysis::persistentOutput(PersistentOStream & os) const { os << nb << ounit(db, InvGeV) << nq << ounit(dq, GeV) << sumn; } void ElasticXSecAnalysis::persistentInput(PersistentIStream & is, int) { is >> nb >> iunit(db, InvGeV) >> nq >> iunit(dq, GeV) >> sumn; } // Static variable needed for the type description system in ThePEG. #include "ThePEG/Utilities/DescribeClass.h" DescribeClass describeDIPSYElasticXSecAnalysis("DIPSY::ElasticXSecAnalysis", "ElasticXSecAnalysis.so"); void ElasticXSecAnalysis::Init() { static Parameter interfaceNBins ("NBins", "Number of bins in impact parameter.", &ElasticXSecAnalysis::nb, 100, 1, 0, true, false, Interface::lowerlim); static Parameter interfaceDeltaB ("DeltaB", "Size of intervals in impact parameter.", &ElasticXSecAnalysis::db, InvGeV, 0.1*InvGeV, 0.0*InvGeV, 0.0*InvGeV, true, false, Interface::lowerlim); static Parameter interfaceNqBins ("NqBins", "Number of bins in exchanged momentum q.", &ElasticXSecAnalysis::nq, 100, 1, 0, true, false, Interface::lowerlim); static Parameter interfaceDeltaq ("Deltaq", "Size of intervals in exchanged momentum q.", &ElasticXSecAnalysis::dq, GeV, 0.1*GeV, 0.0*GeV, 0.0*GeV, true, false, Interface::lowerlim); static ClassDocumentation documentation ("There is no documentation for the ElasticXSecAnalysis class"); } diff --git a/DIPSY/Emitter.cc b/DIPSY/Emitter.cc --- a/DIPSY/Emitter.cc +++ b/DIPSY/Emitter.cc @@ -1,1449 +1,1449 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the Emitter class. // //Commented #include "Emitter.h" #include "Parton.h" #include "ShadowParton.h" #include "Dipole.h" #include "DipoleState.h" #include "EffectiveParton.h" #include "ThePEG/Utilities/Current.h" #include "DipoleEventHandler.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Utilities/Throw.h" #include "ThePEG/Utilities/DebugItem.h" #include #ifdef ThePEG_TEMPLATES_IN_CC_FILE // #include "Emitter.tcc" #endif #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "gsl/gsl_sf_bessel.h" using namespace DIPSY; Emitter::~Emitter() {} InvEnergy2 Emitter::size2(const Dipole & d) const { return size2(d.size2()); } InvEnergy Emitter::size(const Dipole & d) const { return size(d.size()); } /* * Just a shortcut to access the input parameter from the Current handler. */ InvEnergy Emitter::rMax() const { return theRMax > 0.0*InvGeV? theRMax: Current()->rMax(); } /* * Shortcut to access running alpha from the Current handler. */ double Emitter::alphaSr(InvEnergy r) const { return Current()->alphaSr(r); } /* * Shortcut to access running alpha from the Current handler. */ double Emitter::alphaS(Energy mu) const { return Current()->alphaS(mu); } /* * The veto check for the overestimates done previously. * This calculates the overestimated emission probability, and checks the * actual probability it should have been in this point, and then returns * true or false randomly depending on the ratio. * Note that this is not the final distribution, as there are still more * vetos done later. */ bool Emitter::OEVeto(DipolePtr dip, double y0, Parton::Point p) const { //set up dipole sizes. InvEnergy R13 = (dip->effectivePartons().first->position() - p).pt(); InvEnergy R23 = (dip->effectivePartons().second->position() - p).pt(); InvEnergy R12 = dip->size(); //Too large dipoles messes up the bessel functions, and will not make it //through the p- veto anyways, so can be vetoed already now, to avoid //errors from the bessel function. if(R13*GeV > 100.0) return true; if(R23*GeV > 100.0) return true; if(R12*GeV > 100.0) return false; //some more set up. double bess13 = gsl_sf_bessel_K1(R13/rMax()); double bess23 = gsl_sf_bessel_K1(R23/rMax()); //this is the correct probability distribution used in the paper. Energy2 correctDist = alphaBarr(min(min(R13,R23),R12))/(M_PI*2.0*sqr(rMax()))* (sqr(bess13) + sqr(bess23) - (sqr(R13) + sqr(R23) - sqr(R12))/ (R13*R23)*bess13*bess23); // If we create dipoles which are larger than the original, the // original partons will be distributed as dpt2/pt4. Here we may // include an extra fudge factor to emulate a matrix element // correction. if ( R13 > R12 && R23 > R12 && Current()->fudgeME() ) correctDist *= 1.0 - 1.0/(1.0 + cosh(dip->partons().first->y() - dip->partons().second->y())); //Now calculate the overestimated distribution in the same way as it is done in gerateY() and generateXT(). double Coe = alphaBarr(R12/2.0)/M_PI* sqr(gsl_sf_bessel_K1(R12/(2.0*rMax())))* sqr(R12/(2.0*rMax()))* (R12/(2.0*theRScale)+2.0); if(R12>2.0*rMax()) //double check that this is ok!!!! Coe *= sqrt(R12/(2.0*rMax()))* exp(R12/(rMax())-2.0); //this is the overestime Energy2 overestimate = Coe*(1.0/(sqr(R13)*(R13/theRScale+2.0)) + 1.0/(sqr(R23)*(R23/theRScale+2.0))); //if the overestimate is ok, this should never happen. if( correctDist/overestimate > 1.0 ) Throw() << "In DIPSY::Emitter " << name() << ": XT keep prob is " << correctDist/overestimate << " (r12 = " << R12*GeV << ", Rr13 = " << R13*GeV << ", r23 = " << R23*GeV << ")" << Exception::warning; //generate a random number and check if veto or not. if(correctDist/overestimate>UseRandom::rnd()) return false; else return true; } /* * The veto check for the overestimates done previously using shadows. * This calculates the overestimated emission probability, and checks the * actual probability it should have been in this point, and then returns * true or false randomly depending on the ratio. * Note that this is not the final distribution, as there are still more * vetos done later. */ bool Emitter::OEVeto(DipolePtr dip, tSPartonPtr sp1, tSPartonPtr sp2, double y0, Parton::Point p) const { //set up dipole sizes. InvEnergy R13 = (dip->partons().first->position() - p).pt(); InvEnergy R23 = (dip->partons().second->position() - p).pt(); InvEnergy R12 = dip->size(); //Too large dipoles messes up the bessel functions, and will not make it //through the p- veto anyways, so can be vetoed already now, to avoid //errors from the bessel function. if ( R13*GeV > 100.0 || R23*GeV > 100.0 ) return true; if ( R12*GeV > 100.0 ) return false; //some more set up. double bess13 = gsl_sf_bessel_K1(R13/rMax()); double bess23 = gsl_sf_bessel_K1(R23/rMax()); //this is the correct probability distribution used in the paper. Energy2 correctDist = alphaBarr(min(min(R13,R23),R12))/(M_PI*2.0*sqr(rMax()))* (sqr(bess13) + sqr(bess23) - (sqr(R13) + sqr(R23) - sqr(R12))/ (R13*R23)*bess13*bess23); // If we create dipoles which are larger than the original, the // original partons will be distributed as dpt2/pt4. Here we may // include an extra fudge factor to emulate a matrix element // correction. if ( R13 > R12 && R23 > R12 && Current()->fudgeME() ) correctDist *= 1.0 - 1.0/(1.0 + cosh(dip->partons().first->y() - dip->partons().second->y())); //Now calculate the overestimated distribution in the same way as it is done in gerateY() and generateXT(). double Coe = alphaBarr(R12/2.0)/M_PI* sqr(gsl_sf_bessel_K1(R12/(2.0*rMax())))* sqr(R12/(2.0*rMax()))* (R12/(2.0*theRScale)+2.0); if(R12>2.0*rMax()) //double check that this is ok!!!! Coe *= sqrt(R12/(2.0*rMax()))* exp(R12/(rMax())-2.0); //this is the overestime Energy2 overestimate = Coe*(1.0/(sqr(R13)*(R13/theRScale+2.0)) + 1.0/(sqr(R23)*(R23/theRScale+2.0))); //if the overestimate is ok, this should never happen. //TODO: write a proper error message. if ( correctDist/overestimate > 1.0 ) Throw() << "In DIPSY::Emitter " << name() << ": XT keep prob is " << correctDist/overestimate << " (r12 = " << R12*GeV << ", Rr13 = " << R13*GeV << ", r23 = " << R23*GeV << ")" << Exception::warning; //generate a random number and check if veto or not. return !UseRandom::rndbool(correctDist/overestimate); } InvEnergy Emitter::rCut(DipolePtr dip, double y) const { tEffectivePartonPtr p1 = dip->effectivePartons().first; tEffectivePartonPtr p2 = dip->effectivePartons().second; return 0.99*0.5* min(pTScale()/(p1->plus()*exp(y) + p1->pT().pt()/2.0), min(pTScale()/(p2->plus()*exp(y) + p2->pT().pt()/2.0), dip->size()/4.0))/thePlusInflation; // *** TODO *** interface before/after recoil. // InvEnergy cutoff = 0.99* // min(2.0/3.0*pTScale()*exp(-y)/p1->plus(), // min(2.0/3.0*pTScale()*exp(-y)/p2->plus(), // dip->size()/4.0)); //if ordered BEFORE recoil } /* * This corrects the overestimated emission probability in Y used in * generateY(). The correct emission rate is calculated for the * rapidity in question and compared to the overestimate rate used in * generateY(). Note that this is not the final correct * y-distribution, as there are still several vetos to be checked, it * is just a step closer to the correct distribution. */ bool Emitter::YVeto(double y,DipolePtr dip, double Coe, double rateOE) const { //calculate the correct rate at the rapidity y in question and //compare with the calculated overestimated rate according the what //is used in generateY(). return !UseRandom::rndbool(2.0*M_PI*Coe*log(1.0 + 2.0*theRScale/rCut(dip, y))/ rateOE); } InvEnergy Emitter::rCut(DipolePtr dip, tSPartonPtr sp1, tSPartonPtr sp2, double y) const { if ( theMinusOrderingMode < 5 ) return 0.99*0.5* min(pTScale()/(sp1->plus0()*exp(y) + sp1->pT0().pt()/2.0), min(pTScale()/(sp2->plus0()*exp(y) + sp2->pT0().pt()/2.0), dip->size()/4.0))/thePlusInflation; else return 0.99*0.5* min(pTScale()/(sp1->plus()*exp(y)), min(pTScale()/(sp2->plus()*exp(y)), dip->size()/4.0))/thePlusInflation; } /* * This corrects the overestimated emission probability in Y used in generateY(). * The correct emission rate is calculated for the rapidity in question and * compared to the overestimate rate used in generateY(). * Note that this is not the final correct y-distribution, as there are still several * vetos to be checked, it is just a step closer to the correct distribution. */ bool Emitter::YVeto(double y, DipolePtr dip, tSPartonPtr sp1, tSPartonPtr sp2, double Coe, double rateOE) const { //calculate the correct rate at the rapidity y in question and //compare with the calculated overestimated rate according the what //is used in generateY(). return !UseRandom::rndbool(2.0*M_PI*Coe*log(1.0 + 2.0*theRScale/ rCut(dip, sp1, sp2, y))/ rateOE); } /* * Generates a rapidity for the next emission. * The distribution f(y) in this member is using is an overestimate, and will be * vetoed down to correct distribution in the checks of the x_T distribution. * * Already the overestimate f(y) is too messy to generate directly though, * so it has to be done through a further overestimate g(y) > f(y) which is * then vetoed (only depending on y) down to f(y) with YVeto(). * Look at the writeup for more details on f() and g(). */ double Emitter:: generateY(DipolePtr dip, double ymin, double ymax) const { //set up shorter names. tEffectivePartonPtr p1 = dip->effectivePartons().first; tEffectivePartonPtr p2 = dip->effectivePartons().second; InvEnergy r = dip->size(); //To large dipoles will mess up the bessel function, so just shut them // off by emitting after the maximum y. if ( r*GeV > 100.0 ) return ymax + 1.0; //Calculate the overestimated coefficient. See writeup for details. double Coe = alphaBarr(r/2.0)/M_PI* sqr(gsl_sf_bessel_K1(r/(2.0*rMax())))* sqr(r/(2.0*rMax()))* (r/(2.0*theRScale)+2.0); //For assymptotically large dipoles, the overestimated emission rate grows //faster than Coe, so add an extra factor for large dipoles. //this will have to be removed in the veto. if(r>2.0*rMax()) //double check that this is ok!!! Coe *= sqrt(r/(2.0*rMax()))* exp(r/(rMax())-2.0); //calculate the overestimated rate of emission (per unit rapidity). double rateOE = 2.0*M_PI*Coe*log(1.0 + 2.0*theRScale/rCut(dip, ymin)); //generate the rapidity. (see writeup for details.) double y = ymin + log(1.0-log(UseRandom::rnd())/rateOE); //veto to get to correct distribution, recur if vetoed. if(YVeto(y,dip,Coe,rateOE*exp(y-ymin)) && y < ymax) return generateY(dip, y, ymax); else{ return y; } } /* * Generates a rapidity for the next emission using shadows. * The distribution f(y) in this member is using is an overestimate, and will be * vetoed down to correct distribution in the checks of the x_T distribution. * * Already the overestimate f(y) is too messy to generate directly though, * so it has to be done through a further overestimate g(y) > f(y) which is * then vetoed (only depending on y) down to f(y) with YVeto(). * Look at the writeup for more details on f() and g(). */ double Emitter::generateY(DipolePtr dip, tSPartonPtr sp1, tSPartonPtr sp2, double ymin, double ymax) const { //set up shorter names. InvEnergy r = dip->size(); //To large dipoles will mess up the bessel function, so just shut them // off by emitting after the maximum y. if ( r*GeV > 100.0 ) return ymax + 1.0; //Calculate the overestimated coefficient. See writeup for details. double Coe = alphaBarr(r/2.0)/M_PI* sqr(gsl_sf_bessel_K1(r/(2.0*rMax())))* sqr(r/(2.0*rMax()))* (r/(2.0*theRScale)+2.0); //For assymptotically large dipoles, the overestimated emission rate grows //faster than Coe, so add an extra factor for large dipoles. //this will have to be removed in the veto. if(r>2.0*rMax()) //double check that this is ok!!! Coe *= sqrt(r/(2.0*rMax()))* exp(r/(rMax())-2.0); //calculate the overestimated rate of emission (per unit rapidity). double rateOE = 2.0*M_PI*Coe*log(1.0 + 2.0*theRScale/ rCut(dip, sp1, sp2, ymin)); //generate the rapidity. (see writeup for details.) double y = ymin + log(1.0-log(UseRandom::rnd())/rateOE); //veto to get to correct distribution, recur if vetoed. if( YVeto(y, dip, sp1, sp2, Coe, rateOE*exp(y-ymin)) && y < ymax ) return generateY(dip, sp1, sp2, y, ymax); return y; } /* * Generate the transverse position. First generate the distance r * larger than the cutoff used in generateY(), then decide around which * parton, and then the angle. Distributions found in writeup. */ Parton::Point Emitter::generateXT(DipolePtr dip, double y0) const { //set up tEffectivePartonPtr p1 = dip->effectivePartons().first; tEffectivePartonPtr p2 = dip->effectivePartons().second; //The normalisation. See writeup for details. double C2 = 2.0/log(1.0+2.0*theRScale/rCut(dip, y0)); //normalises g(z) //Generate the distance. InvEnergy r = 2.0*theRScale/(exp(2.0*UseRandom::rnd()/C2)-1.0); //tested to give correct distribution C2/(r^3/theRScale+2r^2) //generate the angle. double phi = 2.0*M_PI*UseRandom::rnd(); //decide which parton, and create the Point to be returned. if(UseRandom::rnd()>0.5) return Parton::Point(p1->position().first + cos(phi)*r, p1->position().second + sin(phi)*r); else return Parton::Point(p2->position().first + cos(phi)*r, p2->position().second + sin(phi)*r); } /* * Generate the transverse position. First generate the distance r * larger than the cutoff used in generateY(), then decide around which * parton, and then the angle. Distributions found in writeup. */ Parton::Point Emitter::generateXT(DipolePtr dip, tSPartonPtr sp1, tSPartonPtr sp2, double y0) const { //The normalisation. See writeup for details. double C2 = 2.0/log(1.0 + 2.0*theRScale/rCut(dip, sp1, sp2, y0)); //normalises g(z) //Generate the distance. InvEnergy r = 2.0*theRScale/(exp(2.0*UseRandom::rnd()/C2)-1.0); //tested to give correct distribution C2/(r^3/theRScale+2r^2) // InvEnergy RM2 = rMax()*sqrt(2.0); // double C = sqr(RM2/rCut(dip, sp1, sp2, y0)) + 1.0; // exponential of normalization // InvEnergy rnew = // RM2/sqrt(pow(C + 1.0, UseRandom::rnd()) - 1.0); // // Gives the distribution 1/(r+r^3/2R^2) which is everywhere larger // // than r(K1(r/R)^2. //generate the angle. double phi = 2.0*M_PI*UseRandom::rnd(); //decide which parton, and create the Point to be returned. tPartonPtr pp = UseRandom::rndbool()? dip->partons().first: dip->partons().second; return Point(pp->position().first + cos(phi)*r, pp->position().second + sin(phi)*r); } /* * the main function to be called from outside. Other functions are mainly to help * this one. To get the emission right, several layers of overestimates and vetoes * are used. */ void Emitter::generate(Dipole & dip, double ymin, double ymax) const { if ( dip.partons().first->shadow() ) { if ( theMinusOrderingMode == 6 ) generateWithShadowsAgain(dip, ymin, ymax); else if ( theMinusOrderingMode >= 7 ) generateWithShadowsYetAgain(dip, ymin, ymax); else generateWithShadows(dip, ymin, ymax); return; } //Lowest allowed emission rapidity. Not before any of the partons //in the dipole, and not before the supplied ymin. double y0 = max(ymin,max(dip.partons().first->y(),dip.partons().second->y())); //define the resolved effective partons, as function of the dipole size. //Later, when the transverse position is decided, this will have to //be recalculated with the actual resolution ranges. //This is an overestimate, as later lowering the range can only //decrease the allowed phase space through less p+, and increased p_T. dip.effectivePartons(EffectiveParton::create(*(dip.partons().first), size(dip)), EffectiveParton::create(*(dip.partons().second), size(dip))); //Some renaming to save space later. tEffectivePartonPtr p1 = dip.effectivePartons().first; tEffectivePartonPtr p2 = dip.effectivePartons().second; //We will go through the while loop until something passes all the vetoes //or pass the maximum allowed rapidity ymax. However, put a limit //on the number of trials not to get stuck. So define the count to keep //track. Possibly a for loop would be more appropriate at this point... while ( true ) { //reset the range to the overestimate, as we do not know //what x_T will eb chosen this trial. p1->setRange(size(dip)); p2->setRange(size(dip)); //generate a rapidity, according to an overestimate. y0 = generateY(& dip, y0, ymax); //if the generated rapidity is above the limit, return an empty pointer if ( y0 > ymax ) { dip.generatedGluon(new_ptr(Parton())); dip.generatedY(y0); break; } //generate a transverse position, using an overestimated //phase space. Parton::Point p = generateXT(& dip, y0); //Bring down the overestimate in the distribution //to get the right amplitude. After this, only phase space limitations //left. if(OEVeto(& dip,y0,p)) { continue; } //Set up notation. InvEnergy r13 = (p1->position() - p).pt(); InvEnergy r23 = (p2->position() - p).pt(); InvEnergy r12 = dip.size(); //this is to what extent the first parent emitted, and to what extent the //second one. Here, it is some kind of superposition where they are emitting //together, so both parents recoil a bit, etc. double P1 = sqr(r23)/(sqr(r23) + sqr(r13)); double P2 = sqr(r13)/(sqr(r13) + sqr(r23)); //check how much is actually resolved, small emissions resolve more if ( Current()->emitter().rangeMode() != 1 ) { if ( r13 < size(r12) ) p1->setRange( r13 ); if ( r23 < size(r12) ) p2->setRange( r23 ); } //The transverse momentum of the new parton from the parents. TransverseMomentum v1 = pTScale()*(p - p1->position())/sqr(r13); TransverseMomentum v2 = pTScale()*(p - p2->position())/sqr(r23); //calculate the 4-momentum of the emitted gluon. TransverseMomentum pt = v1 + v2; Energy pplus = pt.pt()*exp(-y0); Energy pminus = pt.pt2()/pplus; //check that there's enough p+ if ( p1->plus() - P1*pplus <= 0.0*GeV ){ continue; } if ( p2->plus() - P2*pplus <= 0.0*GeV ){ continue; } //calculate the new 4-momenta of the recoiled parents. TransverseMomentum pt1 = p1->pT() - v1; TransverseMomentum pt2 = p2->pT() - v2; Energy plus1 = p1->plus() - P1*pplus; Energy plus2 = p2->plus() - P2*pplus; double y1 = log(pt1.pt()/plus1); double y2 = log(pt2.pt()/plus2); Energy minus1 = pt1.pt2()/plus1; Energy minus2 = pt2.pt2()/plus2; //this option use the p- ordering of the non-effective parton, //so p- should be calculated from the non-effective parton. if ( theMinusOrderingMode == 1 ) { minus1 = pt1.pt()*exp(dip.partons().first->y()); minus2 = pt2.pt()*exp(dip.partons().second->y()); } //in the first option, p- is required to be fully ordered with both parents. //in the second option, the parton has to be ordered mainly to the parton that //emitted it most, so it is allowed to be unordered by a factor P1 and P2. //PSInflation is a plain factor that the emission is allowed to be unordered by. if ( bothOrderedEvo() ) { if ( pminus*thePSInflation < max(minus1, minus2)*thePMinusOrdering ) continue; } else { if ( pminus*thePSInflation < max(P1*minus1, P2*minus2)*thePMinusOrdering ) continue; } //check rapidity ordered with the two recoiled parents. if ( y1 > y0 ) { continue; } if ( y2 > y0 ) { continue; } //check that none of the internal partons recoiled over ymax. if ( p1->recoilsOverYMax( v1, P1*pplus, ymax ) ) { continue; } if ( p2->recoilsOverYMax( v2, P2*pplus, ymax ) ) { continue; } //This is a self-consistency check. //If things are donw correctly, then emissions at the limit of the //cutoff in x_T used in generateXT() and generateY() should all be vetoed. //if emissions at the limit go through, it means that we are missing part of //the phase space just within the cutoff, which is bad. // //to check this, the cutoff is decreased by a factor 0.99 in generateY() etc above, //to create the occasional emission in a region that should always be vetoed if the //overestimates are fair. This is a check at the end so that none of these emission //between 1 and 0.99 of the cutoff went through. //TODO: match this with cutoff above //TODO: proper error message. if ( min(r13, r23) < min(2.0/3.0*pTScale()/(p1->plus()*exp(y0)), min(2.0/3.0*pTScale()/(p2->plus()*exp(y0)), dip.size()/4.0)) ) Throw() << "In DIPSY::Emitter " << name() << ": Emission below r-cutoff passed vetos!" << " (r12 = " << ounit(r12, InvGeV) << ", r13 = " << ounit(r13, InvGeV) << ", r23 = " << ounit(r23, InvGeV) << "v1/pt = " << double(min(v1.pt(), v2.pt())/pt.pt()) << ")" << Exception::warning; // passed. Set up a new parton for the dipole with the information of the emission. PartonPtr gluon = new_ptr(Parton()); gluon->position(p); dip.generatedGluon(gluon); dip.generatedY(y0); //leave the while loop. break; } } /* * the main function to be called from outside when using * shadows. Other functions are mainly to help this one. To get the * emission right, several layers of overestimates and vetoes are used. */ void Emitter::generateWithShadows(Dipole & dip, double ymin, double ymax) const { static DebugItem trace("DIPSY::Trace", 9); static DebugItem attraction("DIPSY::Attraction", 9); static DebugItem hardsup("DIPSY::HardSup", 9); if ( trace ) cerr << "Gen " << dip.tag() << endl; // Handy pointers to the partons. tPartonPtr p1 = dip.partons().first; tPartonPtr p2 = dip.partons().second; //First check how far down the history we must consider previous shadows. tSPartonPtr sp1 = dip.partons().first->shadow()->resolve(size2(dip), dip.partons().second); tSPartonPtr sp2 = dip.partons().second->shadow()->resolve(size2(dip), dip.partons().first); //Lowest allowed emission rapidity. Not before any of the partons //in the dipole, and not before the supplied ymin. double y0 = max(ymin, max(sp1->y0(), sp2->y0())); ShadowParton::Propagator pp1 = sp1->propagator(size2(dip), p2, -1); ShadowParton::Propagator pp2 = sp2->propagator(size2(dip), p1, -1); p1->plus(max(pp1.colpos, pp1.acopos)); p2->plus(max(pp2.colpos, pp2.acopos)); //We will go through the while loop until something passes all the vetoes //or pass the maximum allowed rapidity ymax. However, put a limit //on the number of trials not to get stuck. So define the count to keep //track. Possibly a for loop would be more appropriate at this point... while ( true ) { //generate a rapidity, according to an overestimate. y0 = generateY(&dip, sp1, sp2, y0, ymax); if ( isnan(y0) ) { Throw() << "Emitter: \"" << name() << "\" caught in infinite loop. Dipole skipped." << Exception::warning; dip.generatedGluon(new_ptr(Parton())); dip.generatedY(ymax + 1.0); return; } //if the generated rapidity is above the limit, return an empty pointer if ( y0 > ymax ) { dip.generatedGluon(new_ptr(Parton())); dip.generatedY(y0); return; } //generate a transverse position, using an overestimated //phase space. Parton::Point p = generateXT(&dip, sp1, sp2, y0); //Bring down the overestimate in the distribution //to get the right amplitude. After this, only phase space limitations //left. if ( OEVeto(&dip, sp1, sp2, y0, p) ) { continue; } //Set up notation. InvEnergy2 r13 = (p1->position() - p).pt2(); InvEnergy2 r23 = (p2->position() - p).pt2(); InvEnergy2 r12 = dip.size2(); // We need to already here decide which parton is emitting. bool firstsplit = UseRandom::rndbool(r23/(r23 + r13)); tPartonPtr pe = firstsplit? p1: p2; tPartonPtr pr = firstsplit? p2: p1; tSPartonPtr spe = firstsplit? sp1: sp2; InvEnergy2 re3 = firstsplit? r13: r23; // The emitting parton may be further resolved by the emission. tSPartonPtr spre = re3 < size2(r12)? pe->shadow()->resolve(re3, pr): spe; //The transverse momentum of the new parton from the emitter. TransverseMomentum pt = pTScale()*(p - pe->position())/re3; if ( hardsup && pt.pt() > 5.0*GeV && !UseRandom::rndbool(5.0*GeV/pt.pt())) continue; if ( attraction ) pt = -pt; Energy pplus = pt.pt()*exp(-y0); Energy pminus = pt.pt2()/pplus; // //check that there's enough p+ // if ( pplus >= spre->plus0() ) continue; // //calculate the new 4-momenta of the recoiled parents. // TransverseMomentum pte = spre->pT() - pt; // Energy pluse = spre->plus0() - pplus; // double ye = log(pte.pt()/pluse); // Energy minuse = pte.pt2()/pluse; // if ( theMinusOrderingMode >= 2 ) { // ShadowParton::Propagator prop = // spre->propagator(min(re3, r12/4.0), pr, -1); // if ( prop.fail ) continue; // pluse = prop.p.plus() - pplus; // if ( pluse <= ZERO ) continue; // pte = TransverseMomentum(prop.p) - pt; // ye = log(pte.pt()/pluse); // if ( theMinusOrderingMode == 4 ) { // minuse = ZERO; // } // else if ( theMinusOrderingMode >= 3 ) { // minuse = pte.pt2()/pluse; // if ( firstsplit ) { // if ( pplus > prop.colpos || pminus < prop.colneg ) continue; // } else { // if ( pplus > prop.acopos || pminus < prop.aconeg ) continue; // } // } // // *** TODO *** fix masses! // } // else if ( theMinusOrderingMode == 1 ) { // minuse = pte.pt()*exp(pe->y()); // } // // Ensure approximate minus ordering. // if ( pminus*thePSInflation < minuse*thePMinusOrdering ) continue; // //check rapidity ordered with the two recoiled parents. // if ( ye > y0 ) continue; if ( theMinusOrderingMode >= 2 ) { ShadowParton::Propagator prop = spre->propagator(min(re3, size2(r12)), pr, -1); if ( prop.fail ) continue; Energy pluse = prop.p.plus() - pplus; if ( pluse <= ZERO ) continue; TransverseMomentum pte = TransverseMomentum(prop.p) - pt; double ye = log(pte.pt()/pluse); if ( ye >= y0 ) continue; if ( theMinusOrderingMode == 3 ) { if ( firstsplit ) { if ( pplus > prop.colpos || pminus < prop.colneg ) continue; } else { if ( pplus > prop.acopos || pminus < prop.aconeg ) continue; } Energy minuse = pte.pt2()/pluse; if ( pminus*thePSInflation < minuse*thePMinusOrdering ) continue; } else if ( theMinusOrderingMode == 2 ) { Energy minuse = pte.pt2()/pluse; if ( pminus*thePSInflation < minuse*thePMinusOrdering ) continue; } else if ( theMinusOrderingMode >= 4 ) { Energy minuse = pt.pt2()/pluse; if ( firstsplit ) { if ( pplus > prop.colpos && pluse > prop.acopos ) continue; if ( pminus < prop.colneg && minuse < prop.aconeg ) continue; } else { if ( pplus > prop.acopos && pluse > prop.colpos ) continue; if ( pminus < prop.aconeg && minuse < prop.colneg ) continue; } } } else { //check that there's enough p+ if ( pplus >= spre->plus0() ) continue; //calculate the new 4-momenta of the recoiled parents. TransverseMomentum pte = spre->pT() - pt; Energy pluse = spre->plus0() - pplus; double ye = log(pte.pt()/pluse); if ( ye > y0 ) continue; Energy minuse = pte.pt2()/pluse; if ( pminus*thePSInflation < minuse*thePMinusOrdering ) continue; } // passed. Set up a new parton for the dipole with the information of the emission. PartonPtr gluon = new_ptr(Parton()); gluon->position(p); gluon->mainParent(pe); dip.generatedGluon(gluon); dip.generatedY(y0); // And we're done! return; } } /* * the main function to be called from outside when using * shadows. Other functions are mainly to help this one. To get the * emission right, several layers of overestimates and vetoes are used. */ void Emitter::generateWithShadowsAgain(Dipole & dip, double ymin, double ymax) const { static DebugItem trace("DIPSY::Trace", 9); if ( trace ) cerr << "Gen " << dip.tag() << endl; // Handy pointers to the partons. tPartonPtr p1 = dip.partons().first; tPartonPtr p2 = dip.partons().second; //First check how far down the history we must consider previous shadows. tSPartonPtr sp10 = p1->shadow()->resolve(dip.size2(), dip.partons().second); tSPartonPtr sp20 = p2->shadow()->resolve(dip.size2(), dip.partons().first); //Lowest allowed emission rapidity. Not before any of the partons //in the dipole, and not before the supplied ymin. double y0 = max(ymin, max(sp10->y0(), sp20->y0())); // Also find the largest plus of previously emitted gluons. ShadowParton::Propagator pp1 = sp10->propagator(dip.size2(), p2, -1); ShadowParton::Propagator pp2 = sp20->propagator(dip.size2(), p1, -1); Energy plus0 = max(max(pp1.colpos, pp1.acopos), max(pp2.colpos, pp2.acopos)); // The maxumum alphabar double alb0 = alphaBarr(dip.size()); // The overall over estimated normalization. double C = splitF? 2.25: 2.0; // This gives the maxumum allowed kt^2 for the highest allowed y Energy2 QM2 = sqr(exp(ymax)*plus0); // The confinement scale Energy2 m02 = sqr(pTScale()/rMax()); // The overestimated kt-integral at maximum rapidity. double intYM = C*alb0*log(QM2/m02 + 1.0); // Place a dummy gluon as emitted; dip.generatedGluon(new_ptr(Parton())); //We will go through the while loop until something passes all the vetoes //or pass the maximum allowed rapidity ymax. while ( true ) { // This gives the maxumum allowed kt^2 for the lowest allowed y Energy2 QL2 = sqr(exp(y0)*plus0); // The overestimated kt-integral at maximum rapidity. double intYL = C*alb0*log(QL2/m02 + 1.0); // We assume that the kt-integral increases approximately with y // according to intY = B+A(y-ymin), with double B = intYL; double A = (intYM - intYL)/(ymax - y0); // Since the second derivative wrt y of the actual integral is // always positive this linear interpolation is always an // overestimate. So we can generate a new y according to it double y = y0 + (sqrt(sqr(B)-2.0*A*log(UseRandom::rnd())) - B)/A; dip.generatedY(y); if ( isnan(y) || y < y0 ) { Throw() << "Emitter: \"" << name() << "\" caught in infinite loop. Dipole skipped." << Exception::warning; dip.generatedY(ymax + 1.0); return; } // If the generated rapidity is above the limit, return an empty pointer if ( y > ymax ) return; Energy2 Q2 = sqr(exp(y)*plus0); double intY = C*alb0*log(Q2/m02 + 1.0); double rat = intY/(A*(y - y0) + B); y0 = y; if ( rat > 1.0000000000001 ) Throw() << Exception::abortnow; if ( !UseRandom::rndbool(rat) ) continue; // Now we have a rapidity, let's generate transverse momenta. Energy2 pt2 = m02*pow(Q2/m02 + 1.0, UseRandom::rnd()) - m02; Energy pt = sqrt(pt2); double phi = UseRandom::rnd(2.0*M_PI); TransverseMomentum kT(pt*sin(phi), pt*cos(phi)); // Then we choose which parton to radiate from and consstruct the // position and distances for the new gluon. bool firstsplit = UseRandom::rndbool(); tPartonPtr pe = firstsplit? p1: p2; tPartonPtr pr = firstsplit? p2: p1; Parton::Point p = pe->position() + pTScale()*kT/pt2; InvEnergy2 d2eg = (pe->position() - p).pt2(); InvEnergy2 d2rg = (pr->position() - p).pt2(); InvEnergy2 d2er = dip.size2(); InvEnergy2 scale = min(d2eg, d2er); // Throw according to overestimate rat = alphaBarr(sqrt(scale))*d2er/(alb0*2.0*(d2eg + d2rg)); if ( !UseRandom::rndbool(rat) ) continue; // Now get resolve the shadow parton actually doing the emission // and calculate the kinematics. tSPartonPtr spe = pe->shadow()->resolve(scale, pr); Energy pplus = pt*exp(-y); Energy pminus = pt2/pplus; ShadowParton::Propagator prop = spe->propagator(scale, pr, -1); if ( prop.fail ) continue; Energy pluse = prop.p.plus() - pplus; if ( pluse <= ZERO ) continue; // Optionally correct for full splitting function. if ( splitF ) { double z = pplus/prop.p.plus(); if ( z > 0.5 ) continue; double rat = sqr(1.0 - z*(1.0 - z))/(1.125*(1.0 - z)); if ( !UseRandom::rndbool(rat) ) continue; if ( splitF > 1 && sqrt(m02/(m02 + pt2)) < UseRandom::rnd() ) continue; } TransverseMomentum pte = TransverseMomentum(prop.p) - kT; double ye = log(pte.pt()/pluse); if ( ye >= y ) continue; Energy minuse = pt2/pluse; if ( firstsplit ) { if ( pplus > prop.colpos && pluse > prop.acopos ) continue; if ( pminus < prop.colneg && minuse < prop.aconeg ) continue; } else { if ( pplus > prop.acopos && pluse > prop.colpos ) continue; if ( pminus < prop.aconeg && minuse < prop.colneg ) continue; } // All kinematical constraints passed. Set up a new parton for the // dipole with the information of the emission. PartonPtr gluon = new_ptr(Parton()); gluon->position(p); gluon->mainParent(pe); gluon->plus(pplus); gluon->pT(kT); gluon->y(y); dip.generatedGluon(gluon); dip.generatedY(y); // And we're done! return; } } /* * the main function to be called from outside when using * shadows. Other functions are mainly to help this one. To get the * emission right, several layers of overestimates and vetoes are used. */ void Emitter::generateWithShadowsYetAgain(Dipole & dip, double ymin, double ymax) const { static DebugItem trace("DIPSY::Trace", 9); if ( trace ) cerr << "Gen " << dip.tag() << endl; // Place a dummy gluon as emitted; PartonPtr gluon = new_ptr(Parton()); dip.generatedGluon(gluon); dip.generatedY(ymax + 1.0); // Handy pointers to the partons. tPartonPtr p1 = dip.partons().first; tPartonPtr p2 = dip.partons().second; // First check how far down the history we must consider previous shadows. tSPartonPtr sp10 = p1->shadow()->resolve(dip.size2(), dip.partons().second); tSPartonPtr sp20 = p2->shadow()->resolve(dip.size2(), dip.partons().first); // Also get the corresponding propagators ShadowParton::Propagator pp1 = sp10->propagator(dip.size2(), p2, -1); ShadowParton::Propagator pp2 = sp20->propagator(dip.size2(), p1, -1); // Check that there is enough energy to do anything. if ( theMinusOrderingMode > 7 && -pp1.p.minus() > dip.dipoleState().collidingEnergy() && -pp2.p.minus() > dip.dipoleState().collidingEnergy() ) return; //Lowest allowed emission rapidity. Not before any of the partons //in the dipole, and not before the supplied ymin. double y0 = max(ymin, max(sp10->y0(), sp20->y0())); // The generation of pt is limited by qplus/pplus = z < 0.5, and // since qplus = qt*exp(-y) we get a limit qt < maxplus*exp(y) where Energy maxplus = max(pp1.p.plus(), pp2.p.plus())/2.0; // The maxumum alphabar double alb0 = alphaBarr(dip.size()); // The overall over estimated normalization. double C = splitF? 2.25: 2.0; // This gives the maxumum allowed kt^2 for the highest allowed y Energy2 QM2 = sqr(exp(ymax)*maxplus); // The confinement scale Energy2 m02 = sqr(pTScale()/rMax()); // The overestimated kt-integral at maximum rapidity. double intYM = C*alb0*log(QM2/m02 + 1.0); if ( intYM <= 0.0 ) return; //We will go through the while loop until something passes all the vetoes //or pass the maximum allowed rapidity ymax. while ( true ) { // This gives the maxumum allowed kt^2 for the lowest allowed y Energy2 QL2 = sqr(exp(y0)*maxplus); // The overestimated kt-integral at maximum rapidity. double intYL = C*alb0*log(QL2/m02 + 1.0); // We assume that the kt-integral increases approximately with y // according to intY = B+A(y-ymin), with double B = intYL; double A = (intYM - intYL)/(ymax - y0); // Since the second derivative wrt y of the actual integral is // always positive this linear interpolation is always an // overestimate. So we can generate a new y according to it double y = y0 + (sqrt(sqr(B)-2.0*A*log(UseRandom::rnd())) - B)/A; if ( isnan(y) || y <= y0 ) { Throw() << "Emitter: \"" << name() << "\" caught in infinite loop. Dipole skipped." << Exception::warning; return; } dip.generatedY(y); // If the generated rapidity is above the limit, return an empty pointer if ( y > ymax ) return; Energy2 Q2 = sqr(exp(y)*maxplus); double intY = C*alb0*log(Q2/m02 + 1.0); double rat = intY/(A*(y - y0) + B); y0 = y; if ( rat > 1.0000000000001 ) Throw() << Exception::abortnow; if ( !UseRandom::rndbool(rat) ) continue; // Now we have a rapidity, let's generate transverse momenta. Energy2 pt2 = m02*pow(Q2/m02 + 1.0, UseRandom::rnd()) - m02; Energy pt = sqrt(pt2); double phi = UseRandom::rnd(2.0*M_PI); TransverseMomentum pT(pt*sin(phi), pt*cos(phi)); // Then we choose which parton to radiate from and construct the // position and distances for the new gluon. bool firstsplit = UseRandom::rndbool(); tPartonPtr pe = firstsplit? p1: p2; tPartonPtr pr = firstsplit? p2: p1; Parton::Point p = pe->position() + pTScale()*pT/pt2; InvEnergy2 d2eg = (pe->position() - p).pt2(); InvEnergy2 d2rg = (pr->position() - p).pt2(); InvEnergy2 d2er = dip.size2(); InvEnergy2 scale = min(d2eg, d2er); // Throw according to overestimate rat = alphaBarr(sqrt(scale))*d2er/(alb0*2.0*(d2eg + d2rg)); if ( !UseRandom::rndbool(rat) ) continue; // Now get resolve the shadow parton actually doing the emission // and calculate the kinematics. tSPartonPtr spe = pe->shadow()->resolve(scale, pr); Energy pplus = pt*exp(-y); ShadowParton::Propagator prop = spe->propagator(scale, pr, -1); if ( prop.fail ) continue; // Check that there is enough energy to do anything. if ( theMinusOrderingMode > 7 && -prop.p.minus() > dip.dipoleState().collidingEnergy() ) continue; double z = pplus/prop.p.plus(); if ( z > 0.5 || z <= 0.0 ) continue; // Optionally correct for full splitting function. if ( splitF && !UseRandom::rndbool(sqr(1.0 - z*(1.0 - z))/(1.125*(1.0 - z))) ) continue; if ( splitF > 1 && sqrt(m02/(m02 + pt2/sqr(splitF))) < UseRandom::rnd() ) continue; if ( splitF < 0 && sqrt(sqrt(m02/(m02 + pt2/sqr(splitF)))) < UseRandom::rnd() ) continue; // *** TODO *** we may want to check here if the emission is at all // possible in the sense that either the emitter or the emitted // can be put on shell with light-cone ordering. But lets keep all // possible emissions for now so that we won't lose anything // (eg. what if both enter in separate interactions?). gluon->position(p); gluon->mainParent(pe); gluon->plus(pplus); gluon->pT(pT); gluon->y(y); dip.generatedY(y); // And we're done! return; } } /* * Maked the dipole actually emit the dipole prepared in generate(), setting up * parents, children, changing 4-momenta etc. */ void Emitter::emit(Dipole & d) const { //some notation. if ( d.partons().first->shadow() ) { emitWithShadows(d); return; } PartonPtr p = d.generatedGluon(); InvEnergy r13 = (d.partons().first->position() - p->position()).pt(); InvEnergy r23 = (d.partons().second->position() - p->position()).pt(); //The recoils. //TODO: use recoil(). TransverseMomentum v1 = pTScale()*(p->position() - d.partons().first->position())/sqr(r13); TransverseMomentum v2 = pTScale()*(p->position() - d.partons().second->position())/sqr(r23); //the ratio each parent emitted the gluon with. double P1 = sqr(r23)/(sqr(r13) + sqr(r23)); double P2 = 1.0 - P1; //set 4-momenta for emission. p->pT(v1 + v2); p->y(d.generatedY()); p->plus(p->pT().pt()*exp(-d.generatedY())); p->minus(p->pT().pt()*exp(d.generatedY())); p->oY(p->y()); //change the dipole structure, generate new colour etc. d.splitDipole(P2); //perform the recoil on the effective partons. //the resolution ranges should be set since the generation of the emission. d.effectivePartons().first->recoil( v1, P1*p->plus() ); d.effectivePartons().second->recoil( v2, P2*p->plus() ); } void Emitter::emitWithShadows(Dipole & d) const { static DebugItem trace("DIPSY::Trace", 9); static DebugItem attraction("DIPSY::Attraction", 9); if ( trace ) cerr << "Emit " << d.tag(); //some notation. PartonPtr p = d.generatedGluon(); // Decide which parton is the emitter. bool em1 = ( p->mainParent() == d.partons().first ); tPartonPtr emitter = em1? d.partons().first: d.partons().second; tPartonPtr recoiler = em1? d.partons().second: d.partons().first; InvEnergy2 res = emitter->dist2(*p); InvEnergy2 scale = min(res, theMinusOrderingMode >= 6? d.size2(): size2(d)); tSPartonPtr sem = emitter->shadow()->resolve(scale, recoiler); TransverseMomentum rec = pTScale()*(p->position() - emitter->position())/res; if ( attraction ) rec = -rec; //change the dipole structure, generate new colour etc. d.splitDipole(em1? 0.0: 1.0); //set 4-momenta for emission. p->pT(rec); p->y(d.generatedY()); p->plus(p->pT().pt()*exp(-d.generatedY())); p->minus(p->pT().pt()*exp(d.generatedY())); p->oY(p->y()); if ( theMinusOrderingMode >= 2 ) { ShadowParton::Propagator prop = sem->propagator(scale, recoiler, -1); emitter->pT(TransverseMomentum(prop.p) - rec); emitter->plus(prop.p.plus() - p->plus()); emitter->y(log(emitter->mt()/emitter->plus())); emitter->minus(emitter->mt2()/emitter->plus()); } else { emitter->pT(sem->pT() - rec); emitter->plus(sem->plus() - p->plus()); emitter->y(log(emitter->pT().pt()/emitter->plus())); emitter->minus(emitter->mt2()/emitter->plus()); } emitter->shadow()->setupEmission(*emitter, *p, *recoiler); d.children().first->setShadows(); d.children().second->setShadows(); if ( trace ) cerr << " -> " << d.children().first->tag() << " + " << d.children().second->tag() << endl; } void Emitter::persistentOutput(PersistentOStream & os) const { os << ounit(thePSInflation, 1.0) << ounit(thePMinusOrdering, 1.0) << ounit(theRScale, InvGeV) << ounit(theRMax, InvGeV) << ounit(thePTScale, 1.0) - << ounit(theBothOrderedEvo, true) - << ounit(theBothOrderedInt, true) - << ounit(theBothOrderedFS, true) - << ounit(theRangeMode, 1) - << ounit(theMinusOrderingMode, 1) << splitF << thePlusInflation << sizeFactor; + << theBothOrderedEvo + << theBothOrderedInt + << theBothOrderedFS + << theRangeMode + << theMinusOrderingMode << splitF << thePlusInflation << sizeFactor; } void Emitter::persistentInput(PersistentIStream & is, int) { is >> iunit(thePSInflation, 1.0) >> iunit(thePMinusOrdering, 1.0) >> iunit(theRScale, InvGeV) >> iunit(theRMax, InvGeV) >> iunit(thePTScale, 1.0) - >> iunit(theBothOrderedEvo, true) - >> iunit(theBothOrderedInt, true) - >> iunit(theBothOrderedFS, true) - >> iunit(theRangeMode, 1) - >> iunit(theMinusOrderingMode, 1) >> splitF >> thePlusInflation >> sizeFactor; + >> theBothOrderedEvo + >> theBothOrderedInt + >> theBothOrderedFS + >> theRangeMode + >> theMinusOrderingMode >> splitF >> thePlusInflation >> sizeFactor; } // Static variable needed for the type description system in ThePEG. #include "ThePEG/Utilities/DescribeClass.h" DescribeClass describeDIPSYEmitter("DIPSY::Emitter", "libAriadne5.so libDIPSY.so"); void Emitter::Init() { static ClassDocumentation documentation ("The Emitter class is responsible for generating and performing " "emissions from dipoles. This base class does the default emission " "strategy."); static Parameter interfaceRScale ("RScale", "Constant used in overestimate of emission probability.", &Emitter::theRScale, InvGeV, 1.0*InvGeV, 0.0*InvGeV, 0.0*InvGeV, true, false, Interface::lowerlim); static Parameter interfacePlusInflation ("PlusInflation", "How much p+ ordering should be enforced in the generation. 1 is normal " "ordering, high numbers are no ordering(energy must still be conserved " "though), low number demands stronger ordering", &Emitter::thePlusInflation, 1.0, 1.0, 0.0, 0.0, true, false, Interface::lowerlim); static Parameter interfaceSizeFactor ("SizeFactor", "The factor dividing the emitting dipole size when determining the resolution of previous emissions or EffectiveParton range.", &Emitter::sizeFactor, 2.0, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfacePSInflation ("PSInflation", "How much p+- ordering should be enforced. 1 is normal ordering, high numbers " "are no ordering(energy must still be conserved though), " "low number demands stronger ordering", &Emitter::thePSInflation, 1.0, 1.0, 0.0, 0.0, true, false, Interface::lowerlim); static Parameter interfacePMinusOrdering ("PMinusOrdering", "An extra factor strengthening the p- ordering on top of the PSInflation." "A large value will suppress large dipoles more.", &Emitter::thePMinusOrdering, 1.0, 1.0, 0.0, 0.0, true, false, Interface::lowerlim); static Parameter interfacePTScale ("PTScale", "If pT is 1/r or 2/r.", &Emitter::thePTScale, 1.0, 1.0, 0.0, 0.0, true, false, Interface::lowerlim); static Parameter interfaceRMax ("RMax", "The confinement scale (in iverse GeV). If set to zero, " "the value of DipoleEventHandler::RMax of the " "controlling event handler will be used.", &Emitter::theRMax, InvGeV, 0.0*InvGeV, 0.0*InvGeV, 0*InvGeV, true, false, Interface::lowerlim); static Switch interfaceBothOrderedEvo ("BothOrderedEvo", "If an emission should be fully ordered with both its parents." "otherwise it will be weighted according to how close they are.", &Emitter::theBothOrderedEvo, false, true, false); static SwitchOption interfaceBothOrderedEvoTrue (interfaceBothOrderedEvo,"True","both parents fully ordered.",true); static SwitchOption interfaceBothOrderedEvoFalse (interfaceBothOrderedEvo,"False","weighted by distance.",false); static Switch interfaceBothOrderedInt ("BothOrderedInt", "If an emission should be fully ordered with both its parents." "otherwise it will be weighted according to how close they are.", &Emitter::theBothOrderedInt, false, true, false); static SwitchOption interfaceBothOrderedIntTrue (interfaceBothOrderedInt,"True","both parents fully ordered.",true); static SwitchOption interfaceBothOrderedIntFalse (interfaceBothOrderedInt,"False","weighted by distance.",false); static Switch interfaceBothOrderedFS ("BothOrderedFS", "If an emission should be fully ordered with both its parents." "otherwise it will be weighted according to how close they are.", &Emitter::theBothOrderedFS, false, true, false); static SwitchOption interfaceBothOrderedFSTrue (interfaceBothOrderedFS,"True","both parents fully ordered.",true); static SwitchOption interfaceBothOrderedFSFalse (interfaceBothOrderedFS,"False","weighted by distance.",false); static Switch interfaceRangeMode ("RangeMode", "How the range of coherenent emissions is determined.", &Emitter::theRangeMode, 0, true, false); static SwitchOption interfaceRangeModeMin (interfaceRangeMode, "Min", "minimum of half mother dipole and distance to emission. Default.", 0); static SwitchOption interfaceRangeModeMax (interfaceRangeMode, "Mother", "Half distance of mother dipole, no matter how close the emission is.", 1); static Switch interfaceMinusOrderingMode ("MinusOrderingMode", "Sets how the ordering in p- is done in the virtual cascade, in relation to effective partons mainly.", &Emitter::theMinusOrderingMode, 0, true, false); static SwitchOption interfaceMinusOrderingModeEffectiveParton (interfaceMinusOrderingMode, "EffectiveParton", "Uses the momentum of the effective parton to order, both plus and pt.", 0); static SwitchOption interfaceMinusOrderingModeEffectivePT (interfaceMinusOrderingMode, "EffectivePT", "Uses the pt of the effective parton, but the rapidity of the single emitting parton.", 1); static SwitchOption interfaceMinusOrderingModeTrueShadow (interfaceMinusOrderingMode, "TrueShadow", "Use the full shadow mechanism for resolved emissions to get the " "incoming propagator.", 2); static SwitchOption interfaceMinusOrderingModeOrderedShadow (interfaceMinusOrderingMode, "OrderedShadow", "Use the full shadow mechanism for resolved emissions to get the " "incoming propagator and checking ordering with previous emissions.", 3); static SwitchOption interfaceMinusOrderingModeUnorderedShadow (interfaceMinusOrderingMode, "UnorderedShadow", "In shadow mechanism, do not order in emissions - this is anyway done " "later on in the construction of propagators.", 4); static SwitchOption interfaceMinusOrderingModeCutShadow (interfaceMinusOrderingMode, "CutShadow", "In shadow mechanism, do not order in emissions - this is anyway done " "later on in the construction of propagators. But allow it to influence " "the cutoff in dipole sizes.", 5); static SwitchOption interfaceMinusOrderingModePtGen (interfaceMinusOrderingMode, "PtGen", "As cut shadow but completely new generation in transverse momentum.", 6); static SwitchOption interfaceMinusOrderingModePtGenZ (interfaceMinusOrderingMode, "PtGenZ", "As cut shadow but completely new generation in transverse momentum using " "only z < 0.5 to limit transverse momenum.", 7); static SwitchOption interfaceMinusOrderingModePtGenZM (interfaceMinusOrderingMode, "PtGenZM", "As cut shadow but completely new generation in transverse momentum using " "only z < 0.5 to limit transverse momenum. Also limit the negative " "lightcone momenta of the propagators.", 8); static Switch interfaceSplittingFunction ("SplittingFunction", "Determines which splitting function to use.", &Emitter::splitF, 0, true, false); static SwitchOption interfaceSplittingFunctionSmallX (interfaceSplittingFunction, "SmallX", "Only use the leading small-x pole 1/z.", 0); static SwitchOption interfaceSplittingFunctionFullAP (interfaceSplittingFunction, "FullAP", "Use the full Altarelli-Parisi splitting function.", 1); static SwitchOption interfaceSplittingFunctionFullAPkTsup (interfaceSplittingFunction, "FullAPkTsup", "Use the full Altarelli-Parisi splitting function and an " "additionan suppression of large kt", 2); static SwitchOption interfaceSplittingFunctionFullAPkTsup3 (interfaceSplittingFunction, "FullAPkTsup3", "Use the full Altarelli-Parisi splitting function and an " "additionan suppression of large kt", 3); static SwitchOption interfaceSplittingFunctionFullAPkTsup4 (interfaceSplittingFunction, "FullAPkTsup4", "Use the full Altarelli-Parisi splitting function and an " "additionan suppression of large kt", 4); static SwitchOption interfaceSplittingFunctionFullAPkTsupm4 (interfaceSplittingFunction, "FullAPkTsupm4", "Use the full Altarelli-Parisi splitting function and an " "additionan suppression of large kt", -4); } diff --git a/DIPSY/EventFiller.cc b/DIPSY/EventFiller.cc --- a/DIPSY/EventFiller.cc +++ b/DIPSY/EventFiller.cc @@ -1,2182 +1,2182 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the EventFiller class. // #include "DipoleEventHandler.h" #include "EventFiller.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/Utilities/Current.h" #include "ThePEG/Utilities/Throw.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/EventRecord/Step.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/EventRecord/SubProcess.h" #include "RealPartonState.h" #include "ParticleInfo.h" #include "ThePEG/Utilities/Debug.h" #include "ThePEG/Utilities/DebugItem.h" #include "ThePEG/Utilities/UtilityBase.h" #include "ThePEG/Utilities/SimplePhaseSpace.h" #include "ThePEG/Handlers/LuminosityFunction.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "../Cascade/EmitterBase.h" #include "Sum20Momentum.h" #include #include using namespace DIPSY; EventFiller::EventFiller() : currentWeight(0.0), theRecoilScheme(0), theSingleMother(0), theDGLAPinPT(0), theEffectiveWeights(0), theFSSwingTime(0.0), theFSSwingTimeStep(0.1), theValenceChargeNormalisation(0), thePTCut(ZERO), theSoftRemove(1), onlyOnce(false), compat(0), debughistos(0) {} EventFiller::~EventFiller() {} IBPtr EventFiller::clone() const { return new_ptr(*this); } IBPtr EventFiller::fullclone() const { return new_ptr(*this); } double EventFiller::fill(Step & step, DipoleEventHandler & eh, tPPair inc, DipoleState & dl, DipoleState & dr, const ImpactParameters & b) const { if ( dl.hasShadows() ) return fillWithShadows(step, eh, inc, b, dl, dr); if ( mode() == 4 ) return fill(step, eh, inc, b, dl, dr); // Get a list of possible dipole-dipole interactions FList fl = eh.xSecFn().flist(dl, dr, b); //Sum over the (ununitarised) interaction probabilities 2*f_{ij}. //Note that the factor 2 is included in flist(), to give the correct //ND interaction probability. double sum = 0.0; for ( FList::iterator it = fl.begin(); it != fl.end(); ++it ) sum += it->first.first; //Just check that they are not all 0. if ( sum == 0.0 ) { return 0.0; } //Non-diffractive interaction probability is 1 - exp(-Sum(2*f_{ij})) double weight = eh.xSecFn().unitarize(sum); //Combine the weights from all the sources. currentWeight = weight*sqr(hbarc)*dr.weight()*dl.weight()*b.weight()/eh.maxXSec(); if ( histdd0) histdd0->fill(dl.getDipoles().size()*dr.getDipoles().size() + 0.5, currentWeight); // Select the interactions which should be performed. pair realStates = selectInteractions(fl, b, eh.xSecFn()); //If no interactions found, discard event. if ( realStates.first->interactions.empty() ) { return 0.0; } //Counts the number of participants in a HI event. //TODO: interface, or trigger on AA. countParticipants(dl, dr, b.bVec().pt()); //Figure out which partons to keep, and which to remove. //Also sort out colour flow, momenta etc. vector strings = extractStrings(dl, dr, realStates, b); DipoleState & finalState = dl; //Discard event if no final state partons were found. if ( strings.empty() || ! fillStep(step, inc, strings) ) { weight = 0.0; currentWeight = 0.0; return weight; } // The last thing we do is to fix up valens configurations. finalState.fixValence(step); return weight; } double EventFiller:: fill(Step & step, DipoleEventHandler & eh, tPPair inc, const ImpactParameters & b, DipoleState & dl, DipoleState & dr) const { if ( dl.hasShadows() ) return fillWithShadows(step, eh, inc, b, dl, dr); // Get a list of possible dipole-dipole interactions InteractionList intl = eh.xSecFn().flist(b, dl, dr); //Sum over the (ununitarised) interaction probabilities 2*f_{ij}. //ND interaction probability. double sum = 0.0; for ( InteractionList::iterator it = intl.begin(); it != intl.end(); ++it ) sum += it->f2; //Just check that they are not all 0. if ( sum <= 0.0 ) { return 0.0; } //Non-diffractive interaction probability is 1 - exp(-Sum(2*f_{ij})) double weight = eh.xSecFn().unitarize(sum); //Combine the weights from all the sources. currentWeight = weight*sqr(hbarc)*dr.weight()*dl.weight()*b.weight()/eh.maxXSec(); if ( histdd0 ) histdd0->fill(dl.getDipoles().size()*dr.getDipoles().size() + 0.5, currentWeight); // Select the interactions which should be performed. pair realStates = selectInteractions(intl, eh.xSecFn()); //If no interactions found, discard event. if ( realStates.first->interactions.empty() ) { return 0.0; } //Counts the number of participants in a HI event. //TODO: interface, or trigger on AA. countParticipants(dl, dr, b.bVec().pt()); //Figure out which partons to keep, and which to remove. //Also sort out colour flow, momenta etc. vector strings = extractStrings(dl, dr, realStates, b); DipoleState & finalState = dl; //Discard event if no final state partons were found. if ( strings.empty() || ! fillStep(step, inc, strings) ) { weight = 0.0; currentWeight = 0.0; return weight; } // The last thing we do is to fix up valens configurations. finalState.fixValence(step); return weight; } double EventFiller:: fillWithShadows(Step & step, DipoleEventHandler & eh, tPPair inc, const ImpactParameters & b, DipoleState & dl, DipoleState & dr) const { // Get a list of possible dipole-dipole interactions InteractionList intl = eh.xSecFn().flist(b, dl, dr); //Sum over the (ununitarised) interaction probabilities 2*f_{ij}. //ND interaction probability. double sum = 0.0; for ( InteractionList::iterator it = intl.begin(); it != intl.end(); ++it ) if ( it->status == DipoleInteraction::ACCEPTED ) sum += it->f2; //Just check that they are not all 0. if ( intl.empty() || sum <= 0.0 ) return 0.0; //Non-diffractive interaction probability is 1 - exp(-Sum(2*f_{ij})) double weight = eh.xSecFn().unitarize(sum); //Combine the weights from all the sources. currentWeight = weight*sqr(hbarc)*dr.weight()*dl.weight()*b.weight()/eh.maxXSec(); InteractionList cleaned; for ( InteractionList::iterator it = intl.begin(); it != intl.end(); ++it ) { if ( histf0 ) { histf0->fill(it->uf2, currentWeight); switch ( it->status ) { case DipoleInteraction::ACCEPTED: histfa->fill(it->uf2, currentWeight); break; case DipoleInteraction::PROPFAIL: histfp->fill(it->uf2, currentWeight); break; case DipoleInteraction::KINEFAIL: histfk->fill(it->uf2, currentWeight); break; case DipoleInteraction::ORDERING: histfo->fill(it->uf2, currentWeight); break; case DipoleInteraction::UNKNOWN: histff->fill(it->uf2, currentWeight); break; } } if ( it->status == DipoleInteraction::ACCEPTED ) cleaned.insert(*it); } intl.swap(cleaned); if ( histdd0 ) { double nij = dl.getDipoles().size()*dr.getDipoles().size() + 0.5; histdd0->fill(nij, currentWeight); histddra->fill(nij, currentWeight*eh.xSecFn().nIAccepted/nij); histddrf->fill(nij, currentWeight*eh.xSecFn().nIBelowCut/nij); histddrp->fill(nij, currentWeight*eh.xSecFn().nIPropFail/nij); histddrk->fill(nij, currentWeight*eh.xSecFn().nIKineFail/nij); histddro->fill(nij, currentWeight*eh.xSecFn().nIOrdering/nij); } InteractionVector interactions = selectShadowInteractions(intl, eh.xSecFn()); //If no interactions found, discard event. if ( interactions.empty() ) return 0.0; //Figure out which partons to keep, and which to remove. //Also sort out colour flow, momenta etc. vector strings = extractShadowStrings(dl, dr, interactions, b); DipoleState & finalState = dl; //Discard event if no final state partons were found. if ( strings.empty() || ! fillStep(step, inc, strings) ) { weight = 0.0; currentWeight = 0.0; return weight; } finalState.checkFSMomentum(step); // The last thing we do is to fix up valens configurations. finalState.fixValence(step); finalState.checkFSMomentum(step); return weight; } void EventFiller::countParticipants(const DipoleState & dl, const DipoleState & dr, const InvEnergy b) const { //The initial dipoles. Note that these will in general have emitted //something, and thus no longer be active. They may have been //reconnected by a new dipole in the absorption process though. vector valenceDip = dl.initialDipoles(); valenceDip.insert(valenceDip.end(), dr.initialDipoles().begin(), dr.initialDipoles().end()); //count the nonparticipating nucleons int untouchedNucleons = 0; for ( int i = 0; i < int(valenceDip.size()); i++ ) { //First find the three valence partons in the nucleon that //the dipole belongs to. //Two are connected to the dipole, easy. tPartonPtr p1 = valenceDip[i]->partons().first; tPartonPtr p2 = valenceDip[i]->partons().second; //The three dipoles in valenceDip are always after each other, //so the third parton can be found in the dipole before or //after (or both). tPartonPtr p3; if ( i != int(valenceDip.size())-1 && valenceDip[i+1]->partons().first == p2 ) p3 = valenceDip[i+1]->partons().second; else if ( i != int(valenceDip.size())-1 && valenceDip[i+1]->partons().second == p1 ) p3 = valenceDip[i+1]->partons().first; else if ( i != 0 && valenceDip[i-1]->partons().first == p2 ) p3 = valenceDip[i-1]->partons().second; else if ( i != 0 && valenceDip[i-1]->partons().second == p1 ) p3 = valenceDip[i-1]->partons().first; //If none of the valence partons have interacted //ie (have children that interacted), the nucleon is considered //to not have interacted. Note that with swings, a single interaction //can make several nucleons participating. if ( !(p1->interacted()) && !(p2->interacted()) && !( p3 && p3->interacted() ) ) { valenceDip[i]->participating(false); untouchedNucleons++; } else valenceDip[i]->participating(true); } //We will triple count, as we loop through all 3 dipoles in //each nucleon. Divide by 3 to make up for this. untouchedNucleons /= 3; } /* * This is the probability that a parton is interacting, given that * the state interacts, but the partons is not selected as primary. * * Prob of p interacting: p * Prob of p interacting, given that the state interacts: x = p/totalP * Prob of p being selected as primary, given state interacts: y = p/sumP * Prob of p being selected as non-primary, given state * interacts: z * x = y + z ==> z = p/totalP - p/sumP * Prob of p not being primary, given state interacts: A = (sumP-p)/sumP * And now what we are looking for: * Prob of p being selected as non-primary, given state interacts * and not selected as primary: B * z = A*B ==> B = z/A = p(1/totalP - 1/sumP)/((sumP-p)/sumP) = * = p(sumP/totalP - 1)/(sumP-p) */ double correctedProb(double totalP, double sumP, double p) { return p*(sumP/totalP - 1.0)/(sumP - p); } pair EventFiller::selectInteractions(const FList & fl, const ImpactParameters & b, const DipoleXSec & xSec) const { if ( histddi ) histddi->fill(fl.size() + 0.5, currentWeight); double sumfij = 0.0; //the sum of the individual nonuntarised int probs double sumUP = 0.0; //The sum of the individual unitarised int probs //Set up a selector, and a map sorted on pt of the interaction. Selector sel; DipolePairMap ordered; //Loop through all possible interactions and fill //@sel and @ordered. for ( FList::const_iterator it = fl.begin(); it != fl.end(); ++it ) { //If no interaction probability, don't bother. if ( it->first.second == 0.0 ) continue; //insert into the selector. sel.insert(it->first.second, it); sumfij += it->first.first; sumUP += it->first.second; if ( histfa ) histfa->fill(it->first.second, currentWeight); //Calculate interaction recoils by calling the DipoleXSec object. DipoleXSec::InteractionRecoil rec = xSec.recoil(it->second.first->partons(), it->second.second->partons(), b); //Insert in @ordered, sorting on max pt recoil. double pt = max(max(rec.first.first.pt(), rec.first.second.pt()), max(rec.second.first.pt(), rec.second.second.pt()))/GeV; ordered.insert(make_pair(pt, it)); // ordered.insert(make_pair(it->first.first, it)); } //interaction probability (for at least one interaction) //of the two states. double totalP = Current()->xSecFn().unitarize(sumfij); //create the real states. RealPartonStatePtr rrs = new_ptr(RealPartonState()); RealPartonStatePtr lrs = new_ptr(RealPartonState()); //Add the valence partons (as they are always real) and save. lrs->addValence(fl.begin()->second.first->dipoleState()); rrs->addValence(fl.begin()->second.second->dipoleState()); lrs->saveState(); rrs->saveState(); DipolePairVector interactions; DipolePairMap potential; DipolePairMap failedPrims; bool found = false; int counter = 0; double maxpt = 0.0; double maxpte = 0.0; while ( !found ) { potential.clear(); interactions.clear(); maxpt = 0.0; maxpte = 0.0; //select a first interaction (since there has to be at least one). FList::const_iterator prim = sel[UseRandom::rnd()]; //Go through the other interactions and check if they are also //interacting. A modified probability is used, to make up for the //bias introduced in selecting a primary interaction. for ( FList::const_iterator it = fl.begin(); it != fl.end(); ++it ) if ( it == prim || correctedProb(totalP,sumUP,it->first.second) > UseRandom::rnd() ) { // DipoleXSec::InteractionRecoil rec = // xSec.recoil(it->second.first->partons(), it->second.second->partons(), // b); // double pt = max(max(rec.first.first.pt(), rec.first.second.pt()), // max(rec.second.first.pt(), rec.second.second.pt()))/GeV; //If the interaction passed the amplitude test, add it to the list //of potential interations. // potential.insert(make_pair(pt, it)); if ( histff ) histff->fill(it->first.second, currentWeight); potential.insert(make_pair(it->first.first, it)); } //Keep track on how many times we have tried to find a consistent //set of interactions. Give up after 10 tries. counter++; if ( counter > 10 ) { overTenEvents += currentWeight; return make_pair(lrs, rrs); } //test all potetential interactions in order, skipping already failed dips. //failed first interactions inserted in failedprims, //and from sel and ordered if first in ordered. int i = 0; set ldips, rdips; for ( DipolePairMap::iterator it = potential.begin(); it != potential.end(); ++it ) { i++; //Check first interaction, and already failed as first. //Then autofail without checking again. if ( failedPrims.find(it->first) != failedPrims.end() && !found ) { continue; } if ( onlyOnce && ( ldips.find(it->second->second.first) != ldips.end() || rdips.find(it->second->second.second) != rdips.end() ) ) continue; //Try to add the interaction. if (addInteraction(it->second, lrs, rrs, interactions, b, xSec)) { found = true; ldips.insert(it->second->second.first); rdips.insert(it->second->second.second); maxpt = max(maxpt, it->first); maxpte = max(maxpte, max(max(it->second->second.first->partons().first->pT().pt(), it->second->second.first->partons().second->pT().pt()), max(it->second->second.second->partons().first->pT().pt(), it->second->second.second->partons().second->pT().pt()))/GeV); } else { //remember if it was first interaction and failed, to not //try it again later. if ( !found ) { failedPrims.insert(*it); if ( it == ordered.begin() ) { ordered.erase(it); sel.erase(it->second); } } } } //if sel (or ordered) empty, give up event. no int can be first. if ( sel.empty() ) return make_pair(lrs, rrs); } //Make sure that the real state partons are on-shell. //May not actually be needed, not sure... TODO: check! for( DipolePairVector::iterator it = interactions.begin(); it != interactions.end(); it++ ) { lrs->setOnShell((*it)->second.first); rrs->setOnShell((*it)->second.second); } for ( RealParton::RealPartonSet::iterator it = lrs->valence.begin(); it != lrs->valence.end(); it++ ) (*it)->setOnShell(); for ( RealParton::RealPartonSet::iterator it = rrs->valence.begin(); it != rrs->valence.end(); it++ ) (*it)->setOnShell(); // *** TO REMOVE *** Temporary analysis if ( histptmax ) { sumwmaxpt += currentWeight; } if ( histdda ) { histdda->fill(lrs->interactions.size() + 0.5, currentWeight); histddp->fill(potential.size() + 0.5, currentWeight); } //return the real states. return make_pair(lrs, rrs); } pair EventFiller::selectInteractions(const InteractionList & intl, const DipoleXSec & xSec) const { InteractionVector interactions; if ( histddi ) histddi->fill(intl.size() + 0.5, currentWeight); double sumfij = 0.0; //the sum of the individual nonuntarised int probs double sumUP = 0.0; //The sum of the individual unitarised int probs //Set up a selector, and a map sorted on pt of the interaction. Selector sel; InteractionPTSet ordered; //Loop through all possible interactions and fill //@sel and @ordered. for ( InteractionList::const_iterator it = intl.begin(); it != intl.end(); ++it ) { //If no interaction probability, don't bother. if ( it->f2 <= 0.0 ) continue; //insert into the selector. sel.insert(it->uf2, it); sumfij += it->f2; sumUP += it->uf2; ordered.insert(it); } //interaction probability (for at least one interaction) //of the two states. double totalP = Current()->xSecFn().unitarize(sumfij); //create the real states. RealPartonStatePtr rrs = new_ptr(RealPartonState()); RealPartonStatePtr lrs = new_ptr(RealPartonState()); //Add the valence partons (as they are always real) and save. lrs->addValence(intl.begin()->dips.first->dipoleState()); rrs->addValence(intl.begin()->dips.second->dipoleState()); lrs->saveState(); rrs->saveState(); InteractionPTSet potential; InteractionPTSet failedPrims; bool found = false; int counter = 0; while ( !found ) { potential.clear(); interactions.clear(); //select a first interaction (since there has to be at least one). InteractionList::const_iterator prim = sel[UseRandom::rnd()]; //Go through the other interactions and check if they are also //interacting. A modified probability is used, to make up for the //bias introduced in selecting a primary interaction. for ( InteractionList::const_iterator it = intl.begin(); it != intl.end(); ++it ) if ( it == prim || correctedProb(totalP,sumUP,it->uf2) > UseRandom::rnd() ) potential.insert(it); //Keep track on how many times we have tried to find a consistent //set of interactions. Give up after 10 tries. counter++; if ( counter > 10 ) { overTenEvents += currentWeight; return make_pair(lrs, rrs); } //test all potetential interactions in order, skipping already failed dips. //failed first interactions inserted in failedprims, //and from sel and ordered if first in ordered. int i = 0; set ldips, rdips; set< pair > intpairs; for ( InteractionPTSet::iterator iit = potential.begin(); iit != potential.end(); ++iit ) { InteractionList::const_iterator it = *iit; i++; //Check first interaction, and already failed as first. //Then autofail without checking again. if ( failedPrims.find(it) != failedPrims.end() && !found ) { continue; } if ( onlyOnce && ( ldips.find(it->dips.first) != ldips.end() || rdips.find(it->dips.second) != rdips.end() ) ) continue; TransverseMomentum recoil = it->rec; it->norec = false; if ( onlyOnce && intpairs.find(it->ints) != intpairs.end() ) { recoil = TransverseMomentum(); it->norec = true; } //Try to add the interaction. if ( addInteraction(it, lrs, rrs, recoil, interactions, xSec) ) { found = true; ldips.insert(it->dips.first); rdips.insert(it->dips.second); intpairs.insert(it->ints); } else { //remember if it was first interaction and failed, to not //try it again later. if ( !found ) { failedPrims.insert(it); if ( iit == ordered.begin() ) { ordered.erase(it); sel.erase(it); } } } } //if sel (or ordered) empty, give up event. no int can be first. if ( sel.empty() ) return make_pair(lrs, rrs); } //Make sure that the real state partons are on-shell. //May not actually be needed, not sure... TODO: check! for( InteractionVector::iterator it = interactions.begin(); it != interactions.end(); it++ ) { lrs->setOnShell((*it)->dips.first); rrs->setOnShell((*it)->dips.second); } for ( RealParton::RealPartonSet::iterator it = lrs->valence.begin(); it != lrs->valence.end(); it++ ) (*it)->setOnShell(); for ( RealParton::RealPartonSet::iterator it = rrs->valence.begin(); it != rrs->valence.end(); it++ ) (*it)->setOnShell(); // *** TO REMOVE *** Temporary analysis if ( histptmax ) { sumwmaxpt += currentWeight; } if ( histdda ) { histdda->fill(lrs->interactions.size() + 0.5, currentWeight); histddp->fill(potential.size() + 0.5, currentWeight); } //return the real states. return make_pair(lrs, rrs); } EventFiller::InteractionVector EventFiller::selectShadowInteractions(const InteractionList & intl, const DipoleXSec & xSec) const { if ( Current()->effectivePartonMode() < -1 ) return selectShadowInteractions2(intl, xSec); InteractionVector interactions; if ( histddi ) histddi->fill(intl.size() + 0.5, currentWeight); tDipoleStatePtr dl = &intl.begin()->dips.first->dipoleState(); tDipoleStatePtr dr = &intl.begin()->dips.second->dipoleState(); double sumfij = 0.0; //the sum of the individual nonuntarised int probs double sumUP = 0.0; //The sum of the individual unitarised int probs //Set up a selector, and a map sorted on pt of the interaction. Selector sel; InteractionPTSet ordered; //Loop through all possible interactions and fill //@sel and @ordered. for ( InteractionList::const_iterator it = intl.begin(); it != intl.end(); ++it ) { //If no interaction probability, don't bother. if ( it->f2 <= 0.0 ) continue; //insert into the selector. sel.insert(it->uf2, it); sumfij += it->f2; sumUP += it->uf2; ordered.insert(it); } //interaction probability (for at least one interaction) //of the two states. double totalP = xSec.unitarize(sumfij); InteractionPTSet potential; InteractionPTSet failedPrims; bool found = false; int counter = 0; while ( !found ) { potential.clear(); interactions.clear(); dl->resetShadows(); dr->resetShadows(); //select a first interaction (since there has to be at least one). InteractionList::const_iterator prim = sel[UseRandom::rnd()]; //Go through the other interactions and check if they are also //interacting. A modified probability is used, to make up for the //bias introduced in selecting a primary interaction. for ( InteractionList::const_iterator it = intl.begin(); it != intl.end(); ++it ) if ( it == prim || correctedProb(totalP,sumUP,it->uf2) > UseRandom::rnd() ) { if ( histff ) histff->fill(it->uf2, currentWeight); potential.insert(it); } //Keep track on how many times we have tried to find a consistent //set of interactions. Give up after 10 tries. counter++; if ( counter > 10 ) { overTenEvents += currentWeight; return interactions; } // Test all potetential interactions in order, skipping already // failed dips. Failed first interactions are inserted in // failedprims, and removed from sel and ordered if first in // ordered. Keep track of each dipole that has interacted, as a // dipole can only interact once. Also keep track of all pairs of // partons that has itneracted, as if the same paie is // rescattered, they should not be given double recoil. int i = 0; set ldips, rdips; set< pair > intpairs; for ( InteractionPTSet::iterator iit = potential.begin(); iit != potential.end(); ++iit ) { InteractionList::const_iterator it = *iit; i++; // Check first interaction, and if already failed as first // autofail it without checking again. if ( failedPrims.find(it) != failedPrims.end() && !found ) continue; // Never let the same dipole interact more than once. if ( ldips.find(it->dips.first) != ldips.end() || rdips.find(it->dips.second) != rdips.end() ) continue; // Try to add the interaction. First prepare by inserting the // interaction at a suitable ShadowParton. interactions.push_back(it); if ( i == 1 && it->check(-1) ) { cerr << "Failed in before prepare:" << endl; interactions[0]->debug(); cerr << "Failed in before prepare:" << endl; } it->id = interactions.size(); it->prepare(); if ( i == 1 && it->check(-1) ) { cerr << "Failed in after prepare:" << endl; interactions[0]->debug(); } // If the same two partons interact twice only give recoil once. it->norec = ( intpairs.find(it->sints) != intpairs.end() ); // We need to check previously accepted interactions as well, so // we have to recheck all. double Ni = interactions.size() + 0.5; if ( histdc0 ) histdc0->fill(Ni, currentWeight); if ( recheckInteractions(interactions, 0) ) { found = true; if ( histdc0 ) histdca->fill(Ni, currentWeight); if ( onlyOnce ) { ldips.insert(it->dips.first); // Prevent dipoles from interacting again. rdips.insert(it->dips.second); } intpairs.clear(); // Re-build all pairs of interacting partons. for ( int i = 0, N = interactions.size(); i < N; ++i ) intpairs.insert(interactions[i]->sints); } else { if ( histdc0 ) { for ( int i = 0, N = interactions.size(); i < N; ++i ) { if ( interactions[i]->status ) { switch ( interactions[i]->status ) { case DipoleInteraction::PROPFAIL: ( i < N - 1 ? histdcfp0: histdcfp )->fill(Ni, currentWeight); break; case DipoleInteraction::KINEFAIL: ( i < N - 1 ? histdcfk0: histdcfk )->fill(Ni, currentWeight); break; case DipoleInteraction::ORDERING: ( i < N - 1 ? histdcfo0: histdcfo )->fill(Ni, currentWeight); break; case DipoleInteraction::UNKNOWN: case DipoleInteraction::ACCEPTED: break; } break; } } } interactions.pop_back(); it->reject(); it->id = -it->id; // *** TODO *** remove this - it's only for debugging. if ( !recheckInteractions(interactions, 0) ) Throw() << "In DIPSY::EventFiller: A previously accepted " << "set of interactions was not accepted in " << "subsequent debug check!" << Exception::abortnow; //remember if it was first interaction and failed, to not //try it again later. if ( !found ) { failedPrims.insert(it); if ( iit == ordered.begin() ) { ordered.erase(it); sel.erase(it); } } } } //if sel (or ordered) empty, give up event. no int can be first. if ( sel.empty() ) return interactions; } // *** TO REMOVE *** Temporary analysis if ( histptmax ) { sumwmaxpt += currentWeight; } if ( histdda ) { histdda->fill(interactions.size() + 0.5, currentWeight); histddp->fill(potential.size() + 0.5, currentWeight); histddff->fill(xSec.nIBelowCut + 0.5, currentWeight); histddfp->fill(xSec.nIPropFail + 0.5, currentWeight); histddfk->fill(xSec.nIKineFail + 0.5, currentWeight); histddfo->fill(xSec.nIOrdering + 0.5, currentWeight); } return interactions; } EventFiller::InteractionVector EventFiller::selectShadowInteractions2(const InteractionList & intl, const DipoleXSec & xSec) const { InteractionVector interactions; if ( histddi ) histddi->fill(intl.size() + 0.5, currentWeight); tDipoleStatePtr dl = &intl.begin()->dips.first->dipoleState(); tDipoleStatePtr dr = &intl.begin()->dips.second->dipoleState(); dl->resetShadows(); dr->resetShadows(); // the sum of the individual nonuntarised interaction strrengths double sumfij = 0.0; // Set up a selector, and a map sorted on pt of the interaction. Selector sel; // Loop through all possible interactions and fill // @sel. for ( InteractionList::const_iterator it = intl.begin(); it != intl.end(); ++it ) { //If no interaction probability, don't bother. if ( it->f2 <= 0.0 ) continue; //insert into the selector. sel.insert(it->prob, it); // Sum up all interactions strengths. sumfij += it->f2; } // The interaction probability (for at least one interaction) // between the two states. double P1 = xSec.unitarize(sumfij); int Nc =0; set ldips, rdips; set< pair > intpairs; while ( interactions.empty() || UseRandom::rndbool(P1) ) { ++Nc; // Select one interaction. InteractionList::const_iterator it = sel[UseRandom::rnd()]; // Correct all other probabilities to find probability that // another interaction takes place sumfij = 0.0; double S1 = sel.sum(); Selector tmpsel; for ( InteractionList::const_iterator itt = intl.begin(); itt != intl.end(); ++itt ) { if ( itt != it && itt->id == 0 && itt->f2 > 0.0 ) { itt->prob = itt->prob*(S1/P1 - 1.0)/(S1 - itt->prob); // corresponds to correctedProbability(). sumfij += -Math::log1m(itt->prob); tmpsel.insert(itt->prob, itt); } } P1 = xSec.unitarize(sumfij); sel.swap(tmpsel); if ( histff ) histff->fill(it->uf2, currentWeight); // Each dipole is only allowed to interact once. if ( ldips.find(it->dips.first) != ldips.end() || rdips.find(it->dips.second) != rdips.end() ) continue; // Try to add the interaction. First prepare by inserting the // interaction next in the list. interactions.push_back(it); it->id = interactions.size(); it->prepare(); // If the same two partons interact twice only give recoil once. it->norec = ( intpairs.find(it->sints) != intpairs.end() ); // We need to check previously accepted interactions as well, so // we have to recheck all. double Ni = interactions.size() + 0.5; if ( histdc0 ) histdc0->fill(Ni, currentWeight); if ( recheckInteractions(interactions, 0) ) { if ( histdc0 ) histdca->fill(Ni, currentWeight); if ( onlyOnce ) { ldips.insert(it->dips.first); // Prevent dipoles from interacting again. rdips.insert(it->dips.second); } intpairs.clear(); // Re-build all pairs of interacting partons. for ( int i = 0, N = interactions.size(); i < N; ++i ) intpairs.insert(interactions[i]->sints); } else { if ( histdc0 ) { for ( int i = 0, N = interactions.size(); i < N; ++i ) { if ( interactions[i]->status ) { switch ( interactions[i]->status ) { case DipoleInteraction::PROPFAIL: ( i < N - 1 ? histdcfp0: histdcfp )->fill(Ni, currentWeight); break; case DipoleInteraction::KINEFAIL: ( i < N - 1 ? histdcfk0: histdcfk )->fill(Ni, currentWeight); break; case DipoleInteraction::ORDERING: ( i < N - 1 ? histdcfo0: histdcfo )->fill(Ni, currentWeight); break; case DipoleInteraction::UNKNOWN: case DipoleInteraction::ACCEPTED: break; } break; } } } interactions.pop_back(); it->reject(); it->id = -it->id; // *** TODO *** remove this - it's only for debugging. // *** BUT *** replace it with something else because the shadow // *** tree is not cleaned otherwise. if ( !recheckInteractions(interactions, 0) ) Throw() << "In DIPSY::EventFiller: A previously accepted " << "set of interactions was not accepted in " << "subsequent debug check!" << Exception::abortnow; } } // *** TO REMOVE *** Temporary analysis if ( histptmax ) { sumwmaxpt += currentWeight; } if ( histdda ) { histdda->fill(interactions.size() + 0.5, currentWeight); histddp->fill(Nc + 0.5, currentWeight); histddff->fill(xSec.nIBelowCut + 0.5, currentWeight); histddfp->fill(xSec.nIPropFail + 0.5, currentWeight); histddfk->fill(xSec.nIKineFail + 0.5, currentWeight); histddfo->fill(xSec.nIOrdering + 0.5, currentWeight); } return interactions; } bool EventFiller:: addInteraction(FList::const_iterator inter, RealPartonStatePtr lrs, RealPartonStatePtr rrs, DipolePairVector & inters, const ImpactParameters & b, const DipoleXSec & xSec) const { rescatter += currentWeight; //With some settings, only some of the partons actually interact. //Check which here. Other tunes will just return 4x true. pair, pair > doesInt = xSec.doesInt(inter->second.first->partons(), inter->second.second->partons(), b); if ( compat ) { pair int0 = xSec.int0Partons(inter->second.first->partons().first, inter->second.first->partons().second, inter->second.second->partons().first, inter->second.second->partons().second, b); doesInt = make_pair(make_pair(int0.first, !int0.first), make_pair(int0.second, !int0.second)); } //Calculate the recoils from the interaction. DipoleXSec::InteractionRecoil recs = xSec.recoil(inter->second.first->partons(), inter->second.second->partons(), b, doesInt); //Add the interacting partons and their parents to the real state //and go through the evolution checking for ordering, local pt-max, etc. if ( !lrs->fullControlEvolution (inter->second.first, inter->second.second, doesInt.first.first, doesInt.first.second, recs.first.first.pt(), recs.first.second.pt()) ) { return false; } //Add the interaction to the other state, and check that as well. if ( !rrs->fullControlEvolution (inter->second.second, inter->second.first, doesInt.second.first, doesInt.second.second, recs.second.first.pt(), recs.second.second.pt()) ) { //If this second evolution failed, remove the interaction from //the first //state by reverting it to the previously saved state. lrs->revertToPrevious(inter->second.first); return false; } //If both evolutions could accomodate the interacting partons, //add the interaction recoil as well, //and check that things still are ok. inters.push_back(inter); if ( !controlRecoils(inters, lrs, rrs, b, xSec, doesInt) ) { //If failed, remove the interaction from the evolutions. lrs->revertToPrevious(inter->second.first); rrs->revertToPrevious(inter->second.second); inters.pop_back(); return false; } //If the interactions was ok, mark the dipoles as interacting //and save the real states. xSec.interact(*inter->second.first, *inter->second.second); // inter->second.first->interact(*inter->second.second); // inter->second.second->interact(*inter->second.first); lrs->saveState(); rrs->saveState(); return true; } bool EventFiller:: addInteraction(InteractionList::const_iterator inter, RealPartonStatePtr lrs, RealPartonStatePtr rrs, const TransverseMomentum & recoil, InteractionVector & inters, const DipoleXSec & xSec) const { rescatter += currentWeight; //Add the interacting partons and their parents to the real state //and go through the evolution checking for ordering, local pt-max, etc. if ( !lrs->singleControlEvolution(inter->dips.first, inter->dips.second, inter->ints.first, recoil) ) return false; //Add the interaction to the other state, and check that as well. if ( !rrs->singleControlEvolution(inter->dips.second, inter->dips.first, inter->ints.second, inter->b->invRotatePT(-recoil)) ) return false; //If both evolutions could accomodate the interacting partons, //add the interaction recoil as well, //and check that things still are ok. inters.push_back(inter); if ( !controlRecoils(inters, lrs, rrs, xSec) ) { //If failed, remove the interaction from the evolutions. lrs->revertToPrevious(inter->dips.first); rrs->revertToPrevious(inter->dips.second); inters.pop_back(); return false; } //If the interactions was ok, mark the dipoles as interacting //and save the real states. xSec.interact(*inter->dips.first, *inter->dips.second); // inter->second.first->interact(*inter->second.second); // inter->second.second->interact(*inter->second.first); lrs->saveState(); rrs->saveState(); return true; } bool EventFiller:: recheckInteractions(const InteractionVector & interactions, int mode) const { for ( int i = 0, N = interactions.size(); i < N; ++i ) { if ( i == 0 ) { interactions[0]->dips.first->dipoleState().resetInteractedShadows(); interactions[0]->dips.second->dipoleState().resetInteractedShadows(); } if ( interactions[i]->check(mode) ) { if ( i == 0 && N == 1 ) { cerr << "Failed in recheck:" << endl; interactions[i]->debug(); } return false; } } return true; } vector EventFiller::extractStrings(DipoleState & dl, DipoleState & dr, pair realStates, const ImpactParameters & b ) const { //Just rename a bit for convenience. DipoleStatePtr rightState = &dr; DipoleStatePtr leftState = &dl; RealPartonStatePtr lrs = realStates.first; RealPartonStatePtr rrs = realStates.second; //grow back the partons marked as virtuals. //This will be the ones without interacting children, but not the //ones removed during ordering/pt-max-fixing. removeVirtuals(leftState); removeVirtuals(rightState); //The unordered and not-ok pt-max were removed by pairing them //up with other partons that should stay. Now merge all the momentum //into a single parton, and flag the others as virtual. lrs->mergeVirtuals(); rrs->mergeVirtuals(); //Save to update the parton information from the realPartons. lrs->saveState(); rrs->saveState(); //A high-pt parton (so very localised in x_T) can not recoil all //of a low-pt (so smeared out in x_T) parent, but will rather shoot //out a recoiling part of the parent. Fix this by replacing recoiled //low-pt parents by a remnant, and a recoiler. lrs->addRecoilers(); rrs->addRecoilers(); //Save states to update partons. lrs->saveState(); rrs->saveState(); //balance p+/p- by moving the entire state. Was first done in the //interaction (where the interacting partons had to provide the //energy), but the modifications here changes kinematics so that //some more balancing may be needed. Should very rarely be //large changes. fixBoost(lrs, rrs); //Translate the right state to it's right place in x_T, //and mirror it in rapidity so that it actually comes from the //other side. Finally merge the two cascades into one state. rightState->translate(b); rightState->mirror(0.0); DipoleStatePtr finalState = leftState->merge(rightState); vector > swinging = Current()->xSecFn().getColourExchanges(lrs, rrs); //swing the interacting dipoles. for ( int i = 0; i < int(swinging.size()); i++ ) { Current()-> xSecFn().reconnect(swinging[i].first, swinging[i].second); } //now remove the partons that were made virtual by mergeVirtuals. //This is so that it should be easier to reconnect the colour //through the interacting dipoles with the state from the other side. removeVirtuals(finalState); //do final state swings, aka pythias colour reconnection. double yrange = FSSwingTime(); double ystep = FSSwingTimeStep(); for ( double y = 0.0; y < yrange; y += ystep ) { finalState->swingFS(y, y + ystep); } // finalState->lambdaMeasure(0.36*GeV2, histDipLength2, histDipMass2); //compensate for the 6 valence charges in the proton finalState->normaliseValenceCharge(theValenceChargeNormalisation); //make sure the non-particpating nucleons (if AA) have the //original colour flow. finalState->restoreNonparticipants(); //try to find and fix any problems or inconsistencies that may have //popped up. Error messages are sent if anything is found. dodgeErrors(finalState); //If you want to save the initial state event to file (mainly AA). //TODO: interface! //TODO: stop event after this. //finalState->saveGluonsToFile(currentWeight); //If you want to make a fancy movie in mathematica of your event. :) // finalState->printForMovie(0, 1000); //Sort the remaining partons in strings. vector ret = finalState->strings(); static DebugItem printfinal("DIPSY::PrintFinal", 6); if ( histptfi ) { double maxpt = 0.0; double maxpti = 0.0; for ( int i = 0, N = ret.size(); i < N; ++i ) for ( int j = 0, M = ret[i].size(); j < M; ++j ) { double pt = ret[i][j]->pT().pt()/GeV; if ( abs(ret[i][j]->y()) < 1.0 ) { histptf->fill(pt, currentWeight); maxpt = max(maxpt, pt); if ( ret[i][j]->interacted() ) { histptfi->fill(ret[i][j]->pT().pt()/GeV, currentWeight); maxpti = max(maxpti, pt); } } if ( printfinal ) { cerr << ( ret[i][j]->interacted()? "*": "-") << ( ret[i][j]->valence()? "v": " ") << ( ret[i][j]->rightMoving()? ">": "<") << setw(9) << ret[i][j]->y() << setw(10) << ret[i][j]->pT().pt()/GeV << setw(10) << ret[i][j]->position().x()/InvGeV << setw(10) << ret[i][j]->position().y()/InvGeV << endl; } histptmax->fill(maxpt, currentWeight); histptmaxi->fill(maxpti, currentWeight); } if ( printfinal ) cerr << endl; } return ret; } vector EventFiller::extractShadowStrings(DipoleState & dl, DipoleState & dr, const InteractionVector & interactions, const ImpactParameters & b ) const { // First we check all interactions again, this time putting relevant // partons on shell. if ( !recheckInteractions(interactions, 1) ) Throw() << "In DIPSY::EventFiller: A previously accepted set of interactions was not " << "accepted in the final check!" << Exception::abortnow; // Translate the right state to it's right place in x_T, // and mirror it in rapidity so that it actually comes from the // other side. Finally merge the two cascades into one state. dr.translate(b); dr.mirror(0.0); DipoleStatePtr finalState = dl.merge(&dr); finalState->checkFSMomentum(); //swing the interacting dipoles. for ( int i = 0, N = interactions.size(); i < N; i++ ) Current()->xSecFn().reconnect(*interactions[i]); finalState->checkFSMomentum(); // Remove all virtual partons removeVirtuals(finalState); finalState->checkFSMomentum(); // Compensate for the 6 valence charges in the proton finalState->normaliseValenceCharge(theValenceChargeNormalisation); finalState->checkFSMomentum(); // Make sure the non-particpating nucleons (if AA) have the // original colour flow. finalState->restoreNonparticipants(); finalState->checkFSMomentum(); //try to find and fix any problems or inconsistencies that may have //popped up. Error messages are sent if anything is found. dodgeErrors(finalState); finalState->checkFSMomentum(); //Sort the remaining partons in strings. vector ret = finalState->strings(); static DebugItem printfinal("DIPSY::PrintFinal", 6); if ( histptfi ) { for ( int i = 0, N = ret.size(); i < N; ++i ) for ( int j = 0, M = ret[i].size(); j < M; ++j ) { if ( abs(ret[i][j]->y()) < 1.0 ) { histptf->fill(ret[i][j]->pT().pt()/GeV, currentWeight); if ( ret[i][j]->interacted() ) histptfi->fill(ret[i][j]->pT().pt()/GeV, currentWeight); } if ( printfinal ) { cerr << ( ret[i][j]->interacted()? "*": "-") << ( ret[i][j]->valence()? "v": " ") << ( ret[i][j]->rightMoving()? ">": "<") << setw(9) << ret[i][j]->y() << setw(10) << ret[i][j]->pT().pt()/GeV << setw(10) << ret[i][j]->position().x()/InvGeV << setw(10) << ret[i][j]->position().y()/InvGeV << endl; } } if ( printfinal ) cerr << endl; } return ret; } bool EventFiller::fillStep (Step & step, tPPair incoming, const vector & strings) const { Direction<0> dir(true); vector< vector > particles(strings.size()); SubProPtr sub = new_ptr(SubProcess(incoming)); for ( int is = 0, NS = strings.size(); is < NS; ++is ) { int N = strings[is].size(); vector removed(N, false); if ( theSoftRemove && pT2Cut() > ZERO && N > 2 ) { bool changed = true; while ( changed ) { changed = false; for ( int i = 0; i < N; ++i ) { if ( removed[i] ) continue; if ( strings[is][i]->valence() && theSoftRemove == 2 ) continue; if ( strings[is][i]->flavour() != ParticleID::g ) continue; int i1 = (N + i - 1)%N; while ( removed[i1] ) i1 = (N + i1 - 1)%N; int i3 = (i + 1)%N; while ( removed[i3] ) i3 = (i3 + 1)%N; if ( i1 == i3 ) continue; if ( invPT2(strings[is], i1, i, i3) < pT2Cut() ) { if ( removeGluon(strings[is], i1, i, i3) ) { removed[i] = changed = true; } else { return false; } } } } } particles[is].resize(N); for ( int i = 0; i < N; ++i ) { if ( removed[i] ) continue; particles[is][i] = strings[is][i]->produceParticle(); int ip = i - 1; while ( ip >= 0 && removed[ip] ) --ip; if ( ip >= 0 ) particles[is][i]->colourConnect(particles[is][ip]); if ( i == N - 1 && strings[is][i]->flavour() == ParticleID::g ) { int i0 = 0; while ( i0 < i && removed[i0] ) ++i0; particles[is][i0]->colourConnect(particles[is][i]); } sub->addOutgoing(particles[is][i]); } if ( strings[is][0]->flavour() == ParticleID::g ) { int i0 = 0; int in = N - 1; while ( i0 < in && removed[i0] ) ++i0; while ( in > i0 && removed[in] ) --in; particles[is][i0]->colourConnect(particles[is][in]); } } step.addSubProcess(sub); return true; } void EventFiller::fixBoost(RealPartonStatePtr lrs, RealPartonStatePtr rrs) const { //access the CoM energy, through a kindof roundabout path... //TODO: must be a better way! Current? PartonPtr dummy = lrs->partons.begin()->first; Energy sqrtS = ((dummy->dipoles().first) ? dummy->dipoles().first:dummy->dipoles().second)->dipoleState().handler().lumiFn().maximumCMEnergy(); //sum left and right p+ and p-. Energy leftPlus = ZERO; Energy leftMinus = ZERO; Energy rightPlus = ZERO; Energy rightMinus = ZERO; //loop and sum over the to-keep partons. for ( map::const_iterator it =lrs->partons.begin(); it != lrs->partons.end(); it++ ) { if ( it->second->keep == RealParton::NO ) continue; leftPlus += it->second->plus; leftMinus += it->second->minus; } for ( map::const_iterator it = rrs->partons.begin(); it != rrs->partons.end(); it++ ) { if ( it->second->keep == RealParton::NO ) continue; rightPlus += it->second->minus; rightMinus += it->second->plus; } //Solve the 2:nd degree equation for how much energy has to be //transfered to set both states on shell. double A = (- rightPlus*rightMinus - sqr(sqrtS) + leftPlus*leftMinus)/(2.0*rightMinus*sqrtS); double B = rightPlus/rightMinus; double y1 = -1.0; double x1 = -1.0; if ( sqr(A) - B > 0.0 ) { //the factor to change right p- with. y1 = - A + sqrt(sqr(A) - B); // double y2 = - A - sqrt(sqr(A) - B); //The factor to change left p+ with. x1 = (y1*sqrtS - rightPlus)/(y1*leftPlus); // double x2 = (y2*sqrtS - rightPlus)/(y2*leftPlus); } //error handling if ( x1 < 0 || y1 < 0 ) { Throw() << "EventFiller::fixBoost gave negative or nan solution to boost equation, " << "will not balance momentum.\n" << "This is probably caused by a rouge gluon being far too virtual.\n" << Exception::warning; return; } //loop again, scaling the p+ and p- according to the solution above. for ( map::const_iterator it = lrs->partons.begin(); it != lrs->partons.end(); it++) { if ( it->second->keep == RealParton::NO ) continue; it->second->plus *= x1; it->second->minus /= x1; } for ( map::const_iterator it = rrs->partons.begin(); it != rrs->partons.end(); it++) { if ( it->second->keep == RealParton::NO ) continue; it->second->minus /= y1; it->second->plus *= y1; } //Save state to transfer the changes to the partons. lrs->saveState(); rrs->saveState(); } // void EventFiller::fixValence(Step & step, DipoleState & dl, DipoleState & dr) const { // list alll = dl.getPartons(); // set vall; // for ( list::iterator pit = alll.begin(); pit != alll.end(); ++pit ) // if ( (**pit).valence() ) vall.insert(*pit); // list allr = dr.getPartons(); // set valr; // for ( list::iterator pit = allr.begin(); pit != allr.end(); ++pit ) // if ( (**pit).valence() ) valr.insert(*pit); // vector lval; // vector rval; // for ( ParticleSet::iterator pit = step.particles().begin(); // pit != step.particles().end(); ++pit ) { // tcPartonPtr p = ParticleInfo::getParton(**pit); // if ( !p ) continue; // if ( member(vall, p) ) lval.push_back(*pit); // else if ( member(valr, p) ) rval.push_back(*pit); // } // if ( UseRandom::rndbool() ) { // dl.fixValence(step, lval); // dr.fixValence(step, rval); // } else { // dr.fixValence(step, rval); // dl.fixValence(step, lval); // } // } void EventFiller::dodgeErrors(DipoleStatePtr finalState) const { list partons = finalState->getPartons(); for ( list::iterator it = partons.begin(); it != partons.end(); it++ ) { PartonPtr p = *it; //check for empty pointers if ( !p ) { Throw() << "dodgeError found empty pointer from getPartons()! :o" << Exception::warning; continue; } //check for colour flow to itself //check for 0 monetum if ( p->pT().pt() == ZERO ) { Throw() << "dodgeError found 0 pt gluon." << Exception::warning; p->pT(TransverseMomentum(UseRandom::rnd()*GeV,UseRandom::rnd()*GeV)); } if ( p->plus() == ZERO || p->minus() == ZERO ) { Throw() << "dodgeError found 0 lightcone momentum." << Exception::warning; p->minus(UseRandom::rnd()*GeV); p->plus(UseRandom::rnd()*GeV); } //check for nan momentum if ( isnan(p->pT().pt()/GeV) ) { Throw() << "dodgeError found NAN pt gluon, fix pt." << Exception::warning; p->pT(TransverseMomentum(UseRandom::rnd()*GeV,UseRandom::rnd()*GeV)); } if ( isnan(p->plus()/GeV) || isnan(p->minus()/GeV) ) { Throw() << "dodgeError found NAN lightcone momentum, fix plus, minus." << Exception::warning; p->minus(UseRandom::rnd()*GeV); p->plus(UseRandom::rnd()*GeV); } //check for negative momentum if ( p->pT().pt() < ZERO ) { Throw() << "dodgeError found negative pt gluon.... >_>, fix pt." << Exception::warning; p->pT(TransverseMomentum(UseRandom::rnd()*GeV,UseRandom::rnd()*GeV)); } if ( p->plus() < ZERO || p->minus() < ZERO ) { Throw() << "dodgeError found negative lightcone momentum, fix plus,minus." << Exception::warning; p->minus(UseRandom::rnd()*GeV); p->plus(UseRandom::rnd()*GeV); //check for off-shell momentum if ( sqr(p->plus()*p->minus() - p->pT().pt2() - sqr(p->mass())) > sqr(sqr(0.01*GeV)) ) { Throw() << "dodgeError found off-shell parton, fix pt." << Exception::warning; if ( p->plus()*p->minus() < sqr(p->mass()) ) { Throw() << "dodgeError found insufficient energy for mass, fix plus,minus." << Exception::warning; double ratio = 2.0*sqr(p->mass())/(p->plus()*p->minus()); //give a bit extra for pt p->plus(p->plus()*sqrt(ratio)); p->minus(p->minus()*sqrt(ratio)); } double mod = sqrt(p->plus()*p->minus() - sqr(p->mass()))/p->pT().pt(); p->pT(p->pT()*mod); } } } } bool EventFiller:: controlRecoils(DipolePairVector & sel, RealPartonStatePtr lrs, RealPartonStatePtr rrs, const ImpactParameters & b, const DipoleXSec & xSec, pair, pair > doesInt) const { //Keep track on which partons are interacting. list >::const_iterator leftDoesInt = lrs->doesInts.begin(); list >::const_iterator rightDoesInt = rrs->doesInts.begin(); //Loop through the interaction, and for ( DipolePairVector::const_iterator inter = sel.begin(); inter != sel.end(); inter++ ) { //Which partons are interacting in this dip-dip interaction pair, pair > trueDoesInt = make_pair(*leftDoesInt++, *rightDoesInt++); //calculate recoils DipoleXSec::InteractionRecoil recoil = xSec.recoil((*inter)->second.first->partons(), (*inter)->second.second->partons(), b, trueDoesInt); //call the DipoleXSec object to check kinematics and vetos //for the interaction. If things don't work, undo the changes. if ( !xSec.doInteraction(recoil, *inter, lrs, rrs, trueDoesInt, b) ) { //revert the total recoil between the states. lrs->totalRecoil -= recoil.first.first + recoil.first.second; rrs->totalRecoil -= recoil.second.first + recoil.second.second; } } return true; } bool EventFiller:: controlRecoils(InteractionVector & sel, RealPartonStatePtr lrs, RealPartonStatePtr rrs, const DipoleXSec & xSec) const { //Keep track on which partons are interacting. list >::const_iterator leftDoesInt = lrs->doesInts.begin(); list >::const_iterator rightDoesInt = rrs->doesInts.begin(); //Loop through the interaction, and for ( InteractionVector::const_iterator inter = sel.begin(); inter != sel.end(); inter++ ) { //Which partons are interacting in this dip-dip interaction pair, pair > trueDoesInt = make_pair(*leftDoesInt, *rightDoesInt); //calculate recoils DipoleXSec::InteractionRecoil recoil = xSec.recoil(**inter); //call the DipoleXSec object to check kinematics and vetos //for the interaction. If things don't work, undo the changes. if ( !xSec.doInteraction(recoil, *inter, lrs, rrs, trueDoesInt) ) { //revert the total recoil between the states. lrs->totalRecoil -= recoil.first.first + recoil.first.second; rrs->totalRecoil -= recoil.second.first + recoil.second.second; } } return true; } void EventFiller::removeVirtuals(DipoleStatePtr state) const { list vP = state->getPartons(); //loop through the partons, and remove the off shell ones. //this only does colour flow. RealPartonState does the kinematics //in mergeVirtuals. for ( list::iterator it = vP.begin(); it != vP.end(); it++) { tPartonPtr p = *it; //only handle off-shell parton. if ( !(p->onShell()) ) { //if there are only 2 or fewer on-shell partons in the colour chain, //it has to be swinged at some point, and better early than late, //as last-second forced swings can lead to silly colour connections. if ( p->nOnShellInChain() < 2 ) { //tell the absorber to find a swing anywhere in the colour chain if ( p->dipoles().first ) absorber()->swingLoop(p->dipoles().first, *state); else absorber()->swingLoop(p->dipoles().second, *state); } //once off-shell loops are handled, absorb the parton. absorber()->removeParton(p); } } } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). -void EventFiller::doinit() throw(InitException) { +void EventFiller::doinit() { HandlerBase::doinit(); } void EventFiller::dofinish() { HandlerBase::dofinish(); if ( sumwmaxpt > 0.0 ) { histptmax->scale(1.0/sumwmaxpt); histptmaxi->scale(1.0/sumwmaxpt); histptf->scale(1.0/sumwmaxpt); histptfi->scale(1.0/sumwmaxpt); histdd0->scale(0.01/sumwmaxpt); histddi->scale(0.01/sumwmaxpt); histdda->scale(1.0/sumwmaxpt); histddp->scale(1.0/sumwmaxpt); histddff->scale(0.01/sumwmaxpt); histddfp->scale(0.01/sumwmaxpt); histddfk->scale(0.01/sumwmaxpt); histddfo->scale(0.01/sumwmaxpt); histddra->scale(0.01/sumwmaxpt); histddrf->scale(0.01/sumwmaxpt); histddrp->scale(0.01/sumwmaxpt); histddrk->scale(0.01/sumwmaxpt); histddro->scale(0.01/sumwmaxpt); histdc0->scale(1.0/sumwmaxpt); histdcfp0->scale(1.0/sumwmaxpt); histdcfk0->scale(1.0/sumwmaxpt); histdcfo0->scale(1.0/sumwmaxpt); histdcfp->scale(1.0/sumwmaxpt); histdcfk->scale(1.0/sumwmaxpt); histdcfo->scale(1.0/sumwmaxpt); histdca->scale(1.0/sumwmaxpt); histf0->scale(100.0/sumwmaxpt); histfa->scale(100.0/sumwmaxpt); histff->scale(100.0/sumwmaxpt); histfp->scale(100.0/sumwmaxpt); histfk->scale(100.0/sumwmaxpt); histfo->scale(100.0/sumwmaxpt); generator()->histogramFactory()->histogramFactory(). divide("/rdca", *histdca, *histdc0); generator()->histogramFactory()->histogramFactory(). divide("/rdcfp", *histdcfp, *histdc0); generator()->histogramFactory()->histogramFactory(). divide("/rdcfk", *histdcfk ,*histdc0); generator()->histogramFactory()->histogramFactory(). divide("/rdcfo", *histdcfo,*histdc0); generator()->histogramFactory()->histogramFactory(). divide("/rdcfp0", *histdcfp0, *histdc0); generator()->histogramFactory()->histogramFactory(). divide("/rdcfk0", *histdcfk0 ,*histdc0); generator()->histogramFactory()->histogramFactory(). divide("/rdcfo0", *histdcfo0,*histdc0); double nd = DipoleInteraction::ofail[10] + DipoleInteraction::ofail[11] + DipoleInteraction::ofail[12] + DipoleInteraction::ofail[13]; double n1d = DipoleInteraction::o1fail[10] + DipoleInteraction::o1fail[11] + DipoleInteraction::o1fail[12] + DipoleInteraction::o1fail[13]; generator()->log() << endl << "Failed ordering in dipole--dipole interactions:" << endl << " total : " << nd << '\t' << n1d << endl << " cL-l : " << DipoleInteraction::ofail[1]/nd << '\t' << DipoleInteraction::o1fail[1]/n1d << endl << " aL-l : " << DipoleInteraction::ofail[2]/nd << '\t' << DipoleInteraction::o1fail[2]/n1d << endl << " cR-r : " << DipoleInteraction::ofail[3]/nd << '\t' << DipoleInteraction::o1fail[3]/n1d << endl << " aR-r : " << DipoleInteraction::ofail[4]/nd << '\t' << DipoleInteraction::o1fail[4]/n1d << endl << " cL-aR : " << DipoleInteraction::ofail[5]/nd << '\t' << DipoleInteraction::o1fail[5]/n1d << endl << " cL-cr : " << DipoleInteraction::ofail[6]/nd << '\t' << DipoleInteraction::o1fail[6]/n1d << endl << " cR-cl : " << DipoleInteraction::ofail[7]/nd << '\t' << DipoleInteraction::o1fail[7]/n1d << endl << " aL-ar : " << DipoleInteraction::ofail[8]/nd << '\t' << DipoleInteraction::o1fail[8]/n1d << endl << " aR-al : " << DipoleInteraction::ofail[9]/nd << '\t' << DipoleInteraction::o1fail[9]/n1d << endl << " ncc : " << DipoleInteraction::ofail[10] << '\t' << DipoleInteraction::o1fail[10] << endl << " nca : " << DipoleInteraction::ofail[11] << '\t' << DipoleInteraction::o1fail[11] << endl << " nac : " << DipoleInteraction::ofail[12] << '\t' << DipoleInteraction::o1fail[12] << endl << " naa : " << DipoleInteraction::ofail[13] << '\t' << DipoleInteraction::o1fail[13] << endl << " ncc0 : " << DipoleInteraction::ofail[14] << '\t' << DipoleInteraction::o1fail[14] << endl << " nca0 : " << DipoleInteraction::ofail[15] << '\t' << DipoleInteraction::o1fail[15] << endl << " nac0 : " << DipoleInteraction::ofail[16] << '\t' << DipoleInteraction::o1fail[16] << endl << " naa0 : " << DipoleInteraction::ofail[17] << '\t' << DipoleInteraction::o1fail[17] << endl << endl; } } void EventFiller::doinitrun() { HandlerBase::doinitrun(); histptmax = FactoryBase::tH1DPtr(); histptmaxi = FactoryBase::tH1DPtr(); histptf = FactoryBase::tH1DPtr(); histptfi = FactoryBase::tH1DPtr(); histdd0 = FactoryBase::tH1DPtr(); histddi = FactoryBase::tH1DPtr(); histdda = FactoryBase::tH1DPtr(); histddp = FactoryBase::tH1DPtr(); histddff = FactoryBase::tH1DPtr(); histddfp = FactoryBase::tH1DPtr(); histddfk = FactoryBase::tH1DPtr(); histddfo = FactoryBase::tH1DPtr(); histddra = FactoryBase::tH1DPtr(); histddrf = FactoryBase::tH1DPtr(); histddrp = FactoryBase::tH1DPtr(); histddrk = FactoryBase::tH1DPtr(); histddro = FactoryBase::tH1DPtr(); histdc0 = FactoryBase::tH1DPtr(); histdcfp0 = FactoryBase::tH1DPtr(); histdcfk0 = FactoryBase::tH1DPtr(); histdcfo0 = FactoryBase::tH1DPtr(); histdcfp = FactoryBase::tH1DPtr(); histdcfk = FactoryBase::tH1DPtr(); histdcfo= FactoryBase::tH1DPtr(); histdca = FactoryBase::tH1DPtr(); histf0 = FactoryBase::tH1DPtr(); histfa = FactoryBase::tH1DPtr(); histff = FactoryBase::tH1DPtr(); histfp = FactoryBase::tH1DPtr(); histfk = FactoryBase::tH1DPtr(); histfo = FactoryBase::tH1DPtr(); sumwmaxpt = 0.0; if ( debughistos && generator()->histogramFactory() ) { generator()->histogramFactory()->initrun(); generator()->histogramFactory()->registerClient(this); histptmax = generator()->histogramFactory()->createHistogram1D ("ptma",100,0.0,100.0); histptmaxi = generator()->histogramFactory()->createHistogram1D ("ptmi",100,0.0,100.0); histptf = generator()->histogramFactory()->createHistogram1D ("ptfa",100,0.0,100.0); histptfi = generator()->histogramFactory()->createHistogram1D ("ptfi",100,0.0,100.0); histdd0 = generator()->histogramFactory()->createHistogram1D ("pdd0",200,0.0,20000.0); histddi = generator()->histogramFactory()->createHistogram1D ("pddi",200,0.0,20000.0); histdda= generator()->histogramFactory()->createHistogram1D ("pdda",100,0.0,100.0); histddp= generator()->histogramFactory()->createHistogram1D ("pddp",100,0.0,100.0); histddff= generator()->histogramFactory()->createHistogram1D ("pddff",200,0.0,20000.0); histddfp= generator()->histogramFactory()->createHistogram1D ("pddfp",200,0.0,20000.0); histddfk= generator()->histogramFactory()->createHistogram1D ("pddfk",200,0.0,20000.0); histddfo= generator()->histogramFactory()->createHistogram1D ("pddfo",200,0.0,20000.0); histddra= generator()->histogramFactory()->createHistogram1D ("pddra",200,0.0,20000.0); histddrf= generator()->histogramFactory()->createHistogram1D ("pddrf",200,0.0,20000.0); histddrp= generator()->histogramFactory()->createHistogram1D ("pddrp",200,0.0,20000.0); histddrk= generator()->histogramFactory()->createHistogram1D ("pddrk",200,0.0,20000.0); histddro= generator()->histogramFactory()->createHistogram1D ("pddro",200,0.0,20000.0); histdc0= generator()->histogramFactory()->createHistogram1D ("dc0",100,0.0,100.0); histdcfp0= generator()->histogramFactory()->createHistogram1D ("dcfp0",100,0.0,100.0); histdcfk0= generator()->histogramFactory()->createHistogram1D ("dcfk0",100,0.0,100.0); histdcfo0= generator()->histogramFactory()->createHistogram1D ("dcfo0",100,0.0,100.0); histdcfp= generator()->histogramFactory()->createHistogram1D ("dcfp",100,0.0,100.0); histdcfk= generator()->histogramFactory()->createHistogram1D ("dcfk",100,0.0,100.0); histdcfo= generator()->histogramFactory()->createHistogram1D ("dcfo",100,0.0,100.0); histdca= generator()->histogramFactory()->createHistogram1D ("dca",100,0.0,100.0); histf0 = generator()->histogramFactory()->createHistogram1D ("f0",100,0.0,1.0); histfa = generator()->histogramFactory()->createHistogram1D ("fa",100,0.0,1.0); histff = generator()->histogramFactory()->createHistogram1D ("ff",100,0.0,1.0); histfp = generator()->histogramFactory()->createHistogram1D ("fp",100,0.0,1.0); histfk = generator()->histogramFactory()->createHistogram1D ("fk",100,0.0,1.0); histfo = generator()->histogramFactory()->createHistogram1D ("fo",100,0.0,1.0); } } double EventFiller::pTScale(DipoleState & state) const { return state.handler().emitter().pTScale(); } Energy2 EventFiller::invPT2(const String & str, int i1, int i2, int i3) { LorentzMomentum p1 = str[i1]->momentum(); LorentzMomentum p2 = str[i2]->momentum(); LorentzMomentum p3 = str[i3]->momentum(); Energy2 s = (p1 + p2 + p3).m2(); if ( s < sqr(str[i1]->mass() + str[i3]->mass() ) ) Throw() << "DIPSY produced space-like gluons. Three neighboring ones had " << "negative mass squared. This cannot be fixed at the moment. " << "Event discarded." << Exception::eventerror; Energy2 s12 = (p1 + p2).m2(); Energy2 s23 = (p2 + p3).m2(); if ( s12 < ZERO || s23 < ZERO ) return -1.0*GeV2; return s12*s23/s; } bool EventFiller::removeGluon(const String & str, int i1, int i2, int i3) { int c0 = str[i1]->dipoles().first? str[i1]->dipoles().first->colour(): -1; int c1 = str[i1]->dipoles().second->colour(); int c2 = str[i3]->dipoles().first->colour(); int c3 = str[i3]->dipoles().second? str[i3]->dipoles().second->colour(): -1; int cn = -1; if ( c0 == c2 && c1 == c3 ) do { cn = UseRandom::irnd(Current()->nColours()); } while ( cn == c0 || cn == c3 ); else if ( c0 == c2 ) cn = c1; else cn = c2; LorentzMomentum p1 = str[i1]->momentum(); LorentzMomentum p2 = str[i2]->momentum(); LorentzMomentum p3 = str[i3]->momentum(); Sum20Momentum sum20; sum20 << p1 << p2 << p3; LorentzMomentum ptest = p1 + p2; if ( ptest.m2() < Constants::epsilon*1000.0*sqr(ptest.e()) ) { str[i1]->plus(ptest.plus()); str[i1]->pT(TransverseMomentum(ptest.x(), ptest.y())); str[i1]->dipoles().second->colour(cn); str[i3]->dipoles().first->colour(cn); return true; } ptest = p3 + p2; if ( ptest.m2() < Constants::epsilon*1000.0*sqr(ptest.e()) ) { str[i3]->plus(ptest.plus()); str[i3]->pT(TransverseMomentum(ptest.x(), ptest.y())); str[i1]->dipoles().second->colour(cn); str[i3]->dipoles().first->colour(cn); return true; } Energy2 S = (p1 + p2 + p3).m2(); if ( S <= ZERO ) return false; LorentzRotation R = Utilities::boostToCM(makeTriplet(&p1, &p2, &p3)); double Psi = Constants::pi - p3.theta(); double beta = 0.0; Energy W = sqrt(S); double x1 = 2.0*p1.e()/W; double x3 = 2.0*p3.e()/W; bool g1 = str[i1]->flavour() == ParticleID::g; bool g3 = str[i3]->flavour() == ParticleID::g; if ( ( g1 && g3 ) || (!g1 && !g3 ) ) beta = Psi*sqr(x3)/(sqr(x1) + sqr(x3)); // minimize pt else if ( g1 ) beta = Psi; R.rotateY(-beta); R.invert(); Lorentz5Momentum p1n(p1.m()); Lorentz5Momentum p3n(p3.m()); try { SimplePhaseSpace::CMS(p1n, p3n, S, 1.0, 0.0); } catch ( ImpossibleKinematics ) { return false; } p1n.transform(R); p3n.transform(R); str[i1]->plus(p1n.plus()); str[i1]->pT(TransverseMomentum(p1n.x(), p1n.y())); str[i1]->minus(p1n.minus()); str[i3]->plus(p3n.plus()); str[i3]->pT(TransverseMomentum(p3n.x(), p3n.y())); str[i3]->minus(p3n.minus()); str[i1]->dipoles().second->colour(cn); str[i3]->dipoles().first->colour(cn); static DebugItem checkkinematics("DIPSY::CheckKinematics", 6); if ( checkkinematics ) { sum20 >> p1n >> p3n; if ( !sum20 ) Throw() << "DIPSY found energy-momentum non-conservation when removing " "gluon in final state." << Exception::warning; } return true; } void EventFiller::persistentOutput(PersistentOStream & os) const { os << theAbsorber << theRecoilScheme << theMode << theSingleMother << theDGLAPinPT << theEffectiveWeights << theFSSwingTime << theFSSwingTimeStep << theValenceChargeNormalisation << ounit(thePTCut, GeV) << theSoftRemove << onlyOnce << compat << debughistos; } void EventFiller::persistentInput(PersistentIStream & is, int) { is >> theAbsorber >> theRecoilScheme >> theMode >> theSingleMother >> theDGLAPinPT >> theEffectiveWeights >> theFSSwingTime >> theFSSwingTimeStep >> theValenceChargeNormalisation >> iunit(thePTCut, GeV) >> theSoftRemove >> onlyOnce >> compat >> debughistos; } DescribeClass describeDIPSYEventFiller("DIPSY::EventFiller", "libAriadne5.so libDIPSY.so"); void EventFiller::Init() { static ClassDocumentation documentation ("The EventFiller class is able to produce an initial ThePEG::Step " "from two colliding DipoleStates."); static Reference interfaceDipoleAbsorber ("DipoleAbsorber", "The object used to absorb non-interacting dipoles.", &EventFiller::theAbsorber, true, false, true, true, false); static Switch interfaceMode ("Mode", "How the real state is found from the virtual cascade. Speed versus consistency.", &EventFiller::theMode, 0, true, false); static SwitchOption interfaceModeMode (interfaceMode, "Consistent", "The fully consistent version. Not currently reccomended.", 0); static SwitchOption interfaceModeFast (interfaceMode, "Fast", "Checking only the new real partons introduced by each new interaction, rather than rechecking them all. Good for heavy ions. Not currently reccomended.", 1); static SwitchOption interfaceModeSingle (interfaceMode, "SingleSweep", "Checking all partons, but sweeping just once in each direction, making " "it a lot faster. Good for heavy ions. May give an occasional unordered " "chain, but hopefully not too often. The recommended option.", 2); static SwitchOption interfaceModeNonRecursive (interfaceMode, "NonRecursive", "Does all evo no matter what. Then removes biggest problem, and does it " "all over again. Never turns partons back on once switched off.", 3); static SwitchOption interfaceModeNewSingle (interfaceMode, "NewSingle", "A new implementation of SingleSweep.", 4); static SwitchOption interfaceModeNewShadow (interfaceMode, "NewShadow", "New Shadow mode.", 5); static Switch interfaceEffectiveWeights ("EffectiveWeights", "How the p+ and pT recoils are distributed among the single partons in an effective parton.", &EventFiller::theEffectiveWeights, 0, true, false); static SwitchOption interfaceEffectiveWeightsPlusWeighted (interfaceEffectiveWeights, "PlusWeighted", "Weight pt and plus according to p+ of the individual partons.", 0); static SwitchOption interfaceEffectiveWeightsPlusEvenWeighted (interfaceEffectiveWeights, "PlusEvenWeighted", "The plus is distibuted according to the plus of the partons, but the pt is shared evenly among the partons.", 1); static SwitchOption interfaceEffectiveWeightsPlusSingleWeighted (interfaceEffectiveWeights, "PlusSingleWeighted", "The plus is distibuted according to the plus of the partons, but the pt is taken only by the colour connected parton", 2); static Switch interfaceRecoilScheme ("RecoilScheme", "How to give tread the positive light-cone momentum of a recoiling parton.", &EventFiller::theRecoilScheme, 0, true, false); static SwitchOption interfaceRecoilSchemePreservePlus (interfaceRecoilScheme, "PreservePlus", "blaha", 0); static SwitchOption interfaceRecoilSchemeFixedY (interfaceRecoilScheme, "FixedY", "blahaaa", 1); static SwitchOption interfaceRecoilSchemeFrameFan (interfaceRecoilScheme, "FrameFan", "dssklajhls", 2); static Parameter interfaceSingleMother ("SingleMother", "If an emission is regarded to come from a single parton rather than both " " partons in the emitting dipole.", &EventFiller::theSingleMother, 1, 1, 0, 0, true, false, Interface::lowerlim); static Parameter interfaceDGLAPinPT ("DGLAPinPT", "If the DGLAP supression should be made in terms of pt rather than r. " " partons in the emitting dipole.", &EventFiller::theDGLAPinPT, 1, 1, 0, 0, true, false, Interface::lowerlim); static Parameter interfaceFSSwingTimeStep ("FSSwingTimeStep", "How long time steps is are to be used for FS colour reconnections.", &EventFiller::theFSSwingTimeStep, 0.1, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfaceFSSwingTime ("FSSwingTime", "How long time is allowed for FS colour reconnections. 0 turns it off.", &EventFiller::theFSSwingTime, 0.0, 0.0, 0, true, false, Interface::lowerlim); static Switch interfaceValenceChargeNormalisation ("ValenceChargeNormalisation", "How to treat the (too large) colour charge of the valence partons.", &EventFiller::theValenceChargeNormalisation, 0, true, false); static SwitchOption interfaceValenceChargeNormalisationNone (interfaceValenceChargeNormalisation, "None", "Dont do anything.", 0); static SwitchOption interfaceValenceChargeNormalisationSwing (interfaceValenceChargeNormalisation, "Swing", "Swing some of the dipoles going to the valence partons", 1); static Parameter interfacePTCut ("PTCut", "The minimum invariant transverse momentum allowed for a gluon. " "Gluons below the cut will be removed from the final state. " "If zero, no gluons will be removed.", &EventFiller::thePTCut, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, true, false, Interface::lowerlim); static Switch interfaceSoftRemove ("SoftRemove", "Determines if gluons with invariant transverse momentum below " "PTCut should be reabsorbed.", &EventFiller::theSoftRemove, 1, true, false); static SwitchOption interfaceSoftRemoveOff (interfaceSoftRemove, "Off", "No gluons are absorbed", 0); static SwitchOption interfaceSoftRemoveAll (interfaceSoftRemove, "All", "All soft gluons below the cut are absorbed.", 1); static SwitchOption interfaceSoftRemoveNoValence (interfaceSoftRemove, "NoValence", "All except valence gluons are absorbed if below the cut.", 2); static Switch interfaceOnlyOnce ("OnlyOnce", "Do not allow a dipole to interact more than once.", &EventFiller::onlyOnce, false, true, false); static SwitchOption interfaceOnlyOnceManyInteractionsPerDipole (interfaceOnlyOnce, "ManyInteractionsPerDipole", "Allow a dipole to interact several times.", false); static SwitchOption interfaceOnlyOnceOneInteractionPerDipole (interfaceOnlyOnce, "OneInteractionPerDipole", "Only one interaction per dipole.", true); static Parameter interfaceCompatMode ("CompatMode", "Compatibility mode for debugging differences between FList and InteractionList.", &EventFiller::compat, 0, 0, 0, true, false, Interface::lowerlim); static Parameter interfaceDebugHist ("DebugHist", "Emit histograms for debugging.", &EventFiller::debughistos, 0, 0, 0, true, false, Interface::lowerlim); } diff --git a/DIPSY/EventFiller.h b/DIPSY/EventFiller.h --- a/DIPSY/EventFiller.h +++ b/DIPSY/EventFiller.h @@ -1,594 +1,594 @@ // -*- C++ -*- #ifndef DIPSY_EventFiller_H #define DIPSY_EventFiller_H // // This is the declaration of the EventFiller class. // #include "EventFiller.fh" #include "ThePEG/Handlers/HandlerBase.h" #include "DipoleEventHandler.fh" #include "RealPartonState.fh" #include "RealParton.fh" #include "DipoleState.h" #include "ImpactParameters.h" #include "DipoleXSec.h" #include "DipoleAbsorber.h" #include "ThePEG/Utilities/Current.h" #include "ThePEG/Analysis/FactoryBase.h" #ifndef LWH_AIAnalysisFactory_H #ifndef LWH #define LWH ThePEGLWH #endif #include "ThePEG/Analysis/LWH/AnalysisFactory.h" #endif namespace DIPSY { using namespace ThePEG; /** * The EventFiller class is able to produce an initial * ThePEG::Collision from two colliding DipoleStates. * * @see \ref EventFillerInterfaces "The interfaces" * defined for EventFiller. */ class EventFiller: public HandlerBase { public: /** * Copy FList typedef from DipoleXSec. */ typedef DipoleXSec::FList FList; /** * Copy InteractionList typedef from DipoleXSec. */ typedef DipoleInteraction::List InteractionList; /** * Copy InteractionList typedef from DipoleXSec. */ typedef DipoleInteraction::PTSet InteractionPTSet; /** * A String is simply a vector of colour-connected partons. */ typedef DipoleState::String String; /** * A vector of dipole pairs represented as iterators into an FList. */ typedef DipoleXSec::DipolePairVector DipolePairVector; /** * An ordered map of dipole pairs represented as iterators into an * FList. */ typedef DipoleXSec::DipolePairMap DipolePairMap; /** * Simple vector of interactions. */ typedef vector InteractionVector; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ EventFiller(); /** * The destructor. */ virtual ~EventFiller(); //@} public: /** @name Virtual functions which can be overridden in subclasses. */ //@{ /** * Fill the current collision object in the given DipoleEventHandler * with the final state gluons produced when dipole states \a dl and * \a dr collides with impact parameters \a b. * @return the total interaction probability. */ virtual double fill(Step & step, DipoleEventHandler & eh, tPPair inc, DipoleState & dl, DipoleState & dr, const ImpactParameters & b) const; /** * Fill the current collision object in the given DipoleEventHandler * with the final state gluons produced when dipole states \a dl and * \a dr collides with impact parameters \a b. * @return the total interaction probability. */ virtual double fill(Step & step, DipoleEventHandler & eh, tPPair inc, const ImpactParameters & b, DipoleState & dl, DipoleState & dr) const; /** * Fill the current collision object in the given DipoleEventHandler * with the final state gluons produced when dipole states \a dl and * \a dr collides with impact parameters \a b. * @return the total interaction probability. */ virtual double fillWithShadows(Step & step, DipoleEventHandler & eh, tPPair inc, const ImpactParameters & b, DipoleState & dl, DipoleState & dr) const; /** * Select which dipole pairs should interact, and return them in the * order in which they should be processed. */ virtual pair selectInteractions(const FList & fl, const ImpactParameters & b, const DipoleXSec & xSec) const; /** * Select which dipole pairs should interact, and return them in the * order in which they should be processed. */ virtual pair selectInteractions(const InteractionList & intl, const DipoleXSec & xSec) const; /** * Select which dipole pairs should interact, and return them in the * order in which they should be processed. (shadow parton version) */ virtual InteractionVector selectShadowInteractions(const InteractionList & intl, const DipoleXSec & xSec) const; virtual InteractionVector selectShadowInteractions2(const InteractionList & intl, const DipoleXSec & xSec) const; /** * Tries to do the interaction between the real states lrs and rrs with the two dipoles * pointed to by inter, assuming that the interactions in inters already has been tested * and accepted. States collide at impact paramter b and using the recoils in xSec. */ bool addInteraction(FList::const_iterator inter, RealPartonStatePtr lrs, RealPartonStatePtr rrs, DipolePairVector & inters, const ImpactParameters & b, const DipoleXSec & xSec) const ; /** * Tries to do the interaction between the real states lrs and rrs with the two dipoles * pointed to by inter, assuming that the interactions in inters already has been tested * and accepted. States collide at impact paramter b and using the recoils in xSec. */ bool addInteraction(InteractionList::const_iterator inter, RealPartonStatePtr lrs, RealPartonStatePtr rrs, const TransverseMomentum & recoil, InteractionVector & inters, const DipoleXSec & xSec) const ; /** * Go through all previously accepted interactions and check that * they can still be performed. If \a mode > 0, this is the last check * and partons are set on-shell. */ bool recheckInteractions(const InteractionVector & interactions, int mode) const; /** * Extract all strings after according to the given interactions. */ virtual vector extractStrings(DipoleState & dl, DipoleState & dr, pair, const ImpactParameters & b) const; /** * Extract all strings after according to the given interactions. */ virtual vector extractShadowStrings(DipoleState & dl, DipoleState & dr, const InteractionVector & interactions, const ImpactParameters & b) const; /** * Fill the given Step with a SubProcess object using the given * incoming particles and list of strings. */ virtual bool fillStep(Step & step, tPPair incoming, const vector & strings) const; /** * Fix up valens partons if they were not of the correct flavour or * if they should collapse into a hadron. */ // virtual void fixValence(Step & step, DipoleState & dl, DipoleState & dr) const; /** * get the recoil scheme. */ inline int recoilScheme() const { return theRecoilScheme; } /** * set the recoil scheme. */ inline void recoilScheme(int x) { theRecoilScheme = x; } /** * get the mode. */ inline int mode() const { return theMode; } /** * set the mode. */ inline void mode(int x) { theMode = x; } /** * get the singleMother. */ inline int singleMother() const { return theSingleMother; } /** * set the singleMother. */ inline void singleMother(int x) { theSingleMother = x; } /** * get the DGLAPinPT. */ inline int DGLAPinPT() const { return theDGLAPinPT; } /** * set the DGLAPinPT. */ inline void DGLAPinPT(int x) { theDGLAPinPT = x; } /** * get the ValenceChargeNormalisation **/ inline int valenceChargeNormalisation() const { return theValenceChargeNormalisation; } /** * The minimum squared invariant transverse momentum allowed for a * gluon in a string. */ Energy2 pT2Cut() const { return sqr(thePTCut); } /** * Return the squared invariant transverse momentum of gluon \a i2 * in a string given its colour-neighbours \a i1 and \a i3. */ static Energy2 invPT2(const String & str, int i1, int i2, int i3); /** * Remove a gluon \a i2 in a string shuffling its momenum to its * colour-neighbours \a i1 and \a i3. */ static bool removeGluon(const String & str, int i1, int i2, int i3); /** * get the effectiveWeights. */ inline int effectiveWeights() const { return theEffectiveWeights; } /** * get the FS swing time. */ inline double FSSwingTime() const { return theFSSwingTime; } /** * get the step size for the FS swing time. */ inline double FSSwingTimeStep() const { return theFSSwingTimeStep; } //@} public: /** * Get the object used to absorb non-interacting dipoles. */ inline DipoleAbsorberPtr absorber() const { return theAbsorber; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). protected: /** * The weight which will be used for the event being generated. */ mutable double currentWeight; mutable bool fail; /** * Debug/testing */ protected: mutable double nInt; mutable double nInt1; mutable double nTried; mutable double nEvents; mutable double nTestedInts; mutable double foundInt; mutable double failedEvo; mutable double failedRec; mutable double rescatter; mutable double overTenEvents; mutable double rejectedEvents; mutable double nLoops; mutable double nYes; mutable double nNo; mutable double avYInEvo; mutable double avYInInt; protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ - virtual void doinit() throw(InitException); + virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Is this where this should be declared?? :o */ virtual void dofinish(); private: protected: /** * balances p+/p- by moving the entire state in rapidity. Assumed to be * UNMIRRORED states, ie, plus and minus are flipped for the right state. **/ void fixBoost(RealPartonStatePtr lrs, RealPartonStatePtr rrs) const; /** * Checks through the final state and tries to fix the most blatant errors. * Specially tries to catch bad momenta that can cause crashes. **/ void dodgeErrors(DipoleStatePtr finalState) const; /** * Checks if the interacting partons in the current states have enough * p+- to set the other state on shell. */ bool controlRecoils(DipolePairVector & sel, RealPartonStatePtr rrs, RealPartonStatePtr lrs, const ImpactParameters & b, const DipoleXSec & xSec, pair, pair > doesInt) const; /** * Checks if the interacting partons in the current states have enough * p+- to set the other state on shell. */ bool controlRecoils(InteractionVector & sel, RealPartonStatePtr rrs, RealPartonStatePtr lrs, const DipoleXSec & xSec) const; /** * Removes the off shell partons and recouples colour flow. p_mu unchanged. */ void removeVirtuals(DipoleStatePtr state) const; /** * Removes the parton and recouples colour flow. p_mu unchanegd. */ void removeParton(tPartonPtr p) const; /** * find the pT scale through the dipolestates eventhandlers emitter object. */ double pTScale(DipoleState &) const; /** * Takes statistics on the number of participants * in a heavy ion collision. */ void countParticipants(const DipoleState & dl, const DipoleState & dr, const InvEnergy b) const; /** * The object used to absorb non-interacting dipoles. */ DipoleAbsorberPtr theAbsorber; /** * What scheme to use when doing recoils. */ int theRecoilScheme; /** * In what mode to create the real state. Fast vs consistent. */ int theMode; /** * If partons have one or two mothers. */ int theSingleMother; /** * If DGLAP supression is made in terms of pt rather than r. */ int theDGLAPinPT; /** * How to distribute recoil among the members of an effective parton. */ int theEffectiveWeights; /** * How long time (in GeV-1) the FS get's to do colour reconnections. */ double theFSSwingTime; /** * How large time steps (in GeV-1) used in the FS colour * reconnections. */ double theFSSwingTimeStep; /** * How the valence charge is handled. **/ int theValenceChargeNormalisation; /** * The minimum invariant transverse momentum allowed for a gluon in a string. */ Energy thePTCut; /** * Options for removing gluons with too small invariant transverse * momentum. */ int theSoftRemove; /** * Do not allow a dipole to interact more than once. */ bool onlyOnce; public: /** * Compatibility mode for debugging differences between FList and * InteractionList. */ int compat; /** * Emit histograms for debugging */ int debughistos; // *** TO REMOVE *** Temporary analysis mutable FactoryBase::tH1DPtr histptmax, histptmaxi, histptfi, histptf, histdd0, histddi, histdda, histddp, histddff, histddfp, histddfk, histddfo, histddra, histddrf, histddrp, histddrk, histddro, histdc0, histdcfp0, histdcfk0, histdcfo0, histdcfp, histdcfk, histdcfo, histdca, histf0, histfa, histff, histfp, histfk, histfo; mutable double sumwmaxpt; public: /** * Exception class for space-like gluon momenta. */ struct SpaceLikeGluons: public Exception {}; /** * Exception class for space-like gluon momenta. */ struct ConsistencyException: public Exception {}; /** * Exception class for failed gluon removal. */ struct RemoveGluonException: public Exception {}; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ EventFiller & operator=(const EventFiller &); }; } #endif /* DIPSY_EventFiller_H */ diff --git a/DIPSY/PPTune/PPTune.inc b/DIPSY/PPTune/PPTune.inc --- a/DIPSY/PPTune/PPTune.inc +++ b/DIPSY/PPTune/PPTune.inc @@ -1,1010 +1,1034 @@ # -*- eval: (ThePEG-repository-mode) -*- # HOW TO TUNE # # We need to generate a number of yoda files for different energies # different observables and different parameter settings. This can be # done in an semi-automated way. # # For the total and elastic cross sections we do not need to generate # final states and these runs can in principle be done once and for # all. In fact running PP16XSECYM??.run (generated in the SAVERUNYM # just after the line "# 16 inclusive observables" below) will produce # all necessary data. # # This input file is (to make a gross understatement) a terrible # mess. It needs to beprocessed by the script ./expand.pl before going # to setupThePEG and it will produce an awfull amount of .run # files. However doing eg. # > make blaha # in this directory yo will only produce the .run files matching "blaha". # # For the final state you have to run the files generated after the # line "# 16 final state observables" below. You will have one run per # energy in PP16XSECYM@??.run (where @ is some arbitrary letter used # to differentiate between settings). The 7TeV will take quite a while # so it is best to divide it up in smaller runs. Using the scripts # "sub" and "runtag" in ~leif/bin you can start the programs as # follows: # # > sub runtag ./runThePEG, PP16XSECYM@02, PP16XSECYM@09, # PP16XSECYM@71_61-80, PP16XSECYM@71_41-60, # PP16XSECYM@71_21-40, PP16XSECYM@71_1-20 # PP16XSECYM@71_81-100 # # After these runs are done you can start the actual tuning with # professor. First you need to copy the relevant files from the # inclusive runs to match the names of the final states runs as # follows: # > cp PP16XSECYM01.log PP16XSECYM@01.log # > cp PP16XSECYM05.log PP16XSECYM@05.log # > cp PP16XSECYM18.log PP16XSECYM@18.log # > cp PP16XSECYM70.log PP16XSECYM@70.log # then run the mkprof.pl script as follows to get a "global" tune # # > ./mkprof.pl -t -w PPTuneFS00.weights -o PP16XSECYM@00.prof PP16XSECYM@ # preferably redirecting both stdout and stderr to some file (there # will be a lot of output). Similarly # > ./mkprof.pl -t -w PPTuneFS70.weights -o PP16XSECYM@70.prof PP16XSECYM@ # will give the tune restricting the final state data to 7TeV, and # changing all "70" to "09" or "02" will give 900 GeV or 200 GeV to # look at the result check the file # PP16XSECYM@00.prof/tunes/results.pkl or use the following script # > ./profsum.pl PP16XSECYM@00.prof/tunes/results.pkl # To get just a summary. # # After the line "# 16 pipeing the tunes" below you can then pipe the # different tunes, just set the parameters according to the fit, do # > make PPT16XSECYM@ # and run eg. # > sub runtag ./runThePEG, PPT16XSECYM@02, PPT16XSECYM@09, PPT16XSECYM@71, # PPT16XSECYM@0202, PPT16XSECYM@0909, PPT16XSECYM@7170 # # # # cd /DIPSY ## First we setup some previously tuned tuned parameters #read CurrentTune.in read ../Tune31.in ## Now we set up an event generator. cp EventHandler PPEventHandler set stdProton:R0 0.0 set stdAntiProton:R0 0.0 set Proton:R0 0.0 set AntiProton:R0 0.0 set PPEventHandler:WFL stdProton set PPEventHandler:WFR stdProton set PPEventHandler:ConsistencyLevel 1 set PPEventHandler:XSecFn:CheckOffShell false set PPEventHandler:CascadeHandler AriadneCascade set PPEventHandler:HadronizationHandler Frag8 set PPEventHandler:DecayHandler /Defaults/Handlers/StandardDecayHandler create ThePEG::FixedCMSLuminosity PPLumi set PPEventHandler:LuminosityFunction PPLumi cp Generator PPGenerator # erase PPGenerator:AnalysisHandlers[0] set PPGenerator:HistogramFactory NULL set PPGenerator:EventHandler PPEventHandler set PPEventHandler:BGen:Width 5 set PPEventHandler:WFL Proton set PPEventHandler:WFR Proton set PPEventHandler:EventFiller:SoftRemove NoValence set PPEventHandler:FudgeME 1 set PPEventHandler:EventFiller:PTCut 1.0 set FSOrdering:PTMin 1.0 set PPEventHandler:Emitter:PSInflation 1.0 set PPEventHandler:Swinger:Lambda 1.0 set PPEventHandler:EffectivePartonMode Colours set PPEventHandler:CoherenceRange 2.5 ## These are the analysess we will run ## Some semi-inclusive cross section for DIPSY which need at least ## four combinations of left- and right-moving cascades. erase PPEventHandler:AnalysisHandlers[0] erase PPEventHandler:AnalysisHandlers[0] create DIPSY::SemiInclusiveXSecAnalysis SemiIncl SemiInclusiveXSecAnalysis.so insert PPEventHandler:AnalysisHandlers[0] SemiIncl set PPEventHandler:PreSampleL 2 set PPEventHandler:PreSampleR 2 ## This is just to keep track of the progress of a run create DIPSY::AnalysisProgress AnaLog AnalysisProgress.so set AnaLog:Interval 600 insert PPEventHandler:AnalysisHandlers[0] AnaLog ## The sample rates need to be adjusted so that we get a reasonable ## statistics in a reasonable time. It is typically efficient to ## sample a number of impact parameter values for each pair of DIPSY ## cascades. set PPEventHandler:PreSampleB 1 ## We need the same set of parameters for all different energies, so ## we use a separate random generator. cp /Defaults/Random RandomArg set PPGenerator:SeparateRandom RandomArg ## These are the parameters we want to tune ## Now we want to run for all energies and two values for YFrametest set Frag8:Collapser /Ariadne5/Defaults/Collapser # This is the fragmentation parameters tuned without rope and with swing at LEP # ../../src/FTuneSwLEP01.prin set Frag8:FragmentationScheme none set Frag8:StringZ_aLund 0.42 set Frag8:StringZ_bLund 0.40 set Frag8:StringPT_sigma 0.32 set Frag8:StringFlav_probQQtoQ 0.084 set Frag8:StringFlav_probStoUD 0.22 # This is the fragmentation parameters tuned without rope and swing at LEP # ../../src/FTuneLEP01.prin cp Frag8 Frag8Sw0 set Frag8Sw0:StringZ_aLund 0.30 set Frag8Sw0:StringZ_bLund 0.36 set Frag8Sw0:StringPT_sigma 0.32 set Frag8Sw0:StringFlav_probQQtoQ 0.082 set Frag8Sw0:StringFlav_probStoUD 0.22 # TEST fragmentation parameters tuned at LEP without rope and swing with MaxRho = 1 # ../../src/FTuneswLEP03.prin cp Frag8 Frag8Sw2 set Frag8Sw2:StringZ_aLund 0.45 set Frag8Sw2:StringZ_bLund 0.42 set Frag8Sw2:StringPT_sigma 0.32 set Frag8Sw2:StringFlav_probQQtoQ 0.085 set Frag8Sw2:StringFlav_probStoUD 0.22 # This is the fragmentation parameters tuned to rope and default swing at LEP # ../../src/FTuneSwLEP07.prin cp Frag8 Frag8Rope set Frag8Rope:FragmentationScheme dipole set Frag8Rope:StringR0 1.0 set Frag8Rope:Stringm0 0.2 set Frag8Rope:Average false set Frag8Rope:ThrowAway true set Frag8Rope:BaryonSuppression 0.25 set Frag8Rope:StringZ_aLund 0.41 set Frag8Rope:StringZ_bLund 0.37 set Frag8Rope:StringPT_sigma 0.31 set Frag8Rope:StringFlav_probQQtoQ 0.073 set Frag8Rope:StringFlav_probStoUD 0.21 set Frag8Rope:Shoving false set Frag8Rope:AnalysisPath ./ set Frag8Rope:DoAnalysis 0 cp AriadneCascade AriadneNoSwing erase AriadneNoSwing:Emitters[0] set PPGenerator:EventHandler:PreSamples 0 set PPGenerator:EventHandler:YFrametest 0.5 set /DIPSY/PPEventHandler:BaryonSize 0.0 set FSSwinger:SetRmax -2.7 set FSSwinger:MaxRho -2.0 create ThePEG::ProgressLog Logger ProgressLog.so set Logger:Interval 600 create ThePEG::RivetAnalysis RivetTune RivetAnalysis.so insert RivetTune:Paths[0] . insert RivetTune:Analyses[0] ATLAS_2010_S8918562 insert RivetTune:Analyses[0] STAR_2008_S7869363 insert RivetTune:Analyses[0] CMS_2011_S8978280 insert RivetTune:Analyses[0] PYTHIA_TUNING insert PPGenerator:AnalysisHandlers[0] Logger insert PPGenerator:AnalysisHandlers[0] RivetTune set PPGenerator:EventHandler:LuminosityFunction:Energy 7000 set PPGenerator:DumpPeriod 0 cp PPGenerator PPTestTune set PPGenerator:NumberOfEvents 10000 set PPTestTune:NumberOfEvents 100000 +set PPTestTune:MaxErrors 100 create ThePEG::LWHFactory LWHFactory LWHFactory.so set LWHFactory:Suffix dat set LWHFactory:StoreType flat set PPTestTune:HistogramFactory LWHFactory create DIPSY::PTAnalysis PTAnalysis PTAnalysis.so insert PPTestTune:AnalysisHandlers[0] PTAnalysis do PPGenerator:AddRndInterface /DIPSY/PPEventHandler:RMax 100 1.0 5.0 2.9 0.6 do PPGenerator:AddRndInterface /DIPSY/PPEventHandler:LambdaQCD 1 0.10 0.3 0.22 0.04 do PPGenerator:AddRndInterface /DIPSY/PPEventHandler:Emitter:PTScale 1 0.5 2.5 1.4 0.5 do PPGenerator:AddRndInterface /DIPSY/PPEventHandler:Emitter:PMinusOrdering 1 0.5 2.0 1.0 0.2 cp PPGenerator PPXSecGenerator erase PPXSecGenerator:AnalysisHandlers[0] erase PPXSecGenerator:AnalysisHandlers[0] create ThePEG::Settings OnlyXSec do OnlyXSec:set PPXSecGenerator:EventHandler:PreSamples 1000 insert PPXSecGenerator:DefaultObjects[0] OnlyXSec set PPXSecGenerator:NumberOfEvents 0 cp OnlyXSec AddXSec insert PPTestTune:DefaultObjects[0] AddXSec create ThePEG::Settings Default cp Default NoSwing cp Default DefRope do Default:set PPEventHandler:HadronizationHandler Frag8 do Default:set PPEventHandler:CascadeHandler AriadneCascade do NoSwing:set PPEventHandler:HadronizationHandler Frag8Sw0 do NoSwing:set PPEventHandler:CascadeHandler AriadneNoSwing do DefRope:set PPEventHandler:HadronizationHandler Frag8Rope do DefRope:set PPEventHandler:CascadeHandler AriadneCascade cp DefRope DefRop2 cp DefRope Shove00 do Shove00:set Frag8Rope:Shoving true do Shove00:set Frag8Rope:DeltaY 0.1 do Shove00:set Frag8Rope:TShove 0.7 do Shove00:set Frag8Rope:RCutOff 4.0 do Shove00:set Frag8Rope:GAmplitude 0.4 do Shove00:set Frag8Rope:GExponent 0.125 do Shove00:set Frag8Rope:YCutOff 0.2 do Shove00:set Frag8Rope:Lorentz True +do Shove00:set Frag8Rope:DeltaT 0.1 + +cp Shove00 Shove01 +do Shove01:set Frag8Rope:DeltaY 0.5 + +cp Shove00 Shove02 +do Shove02:set Frag8Rope:GAmplitude 4.0 + +cp Shove00 Shove03 +do Shove03:set Frag8Rope:GAmplitude 10.0 +do Shove03:set Frag8Rope:DeltaY 0.5 + +cp Shove00 Shove04 +do Shove04:set Frag8Rope:GAmplitude 4.0 +do Shove04:set Frag8Rope:DeltaY 0.5 insert PPGenerator:DefaultObjects[0] Default insert PPXSecGenerator:DefaultObjects[0] Default insert PPTestTune:DefaultObjects[0] Default cp Default Defaul2 cp Default NewSing do NewSing:set PPEventHandler:EventFiller:Mode NewSingle do NewSing:set PPTestTune:EventHandler:EventFiller:OnlyOnce true do NewSing:set PPEventHandler:FudgeME 2 do NewSing:set PPEventHandler:XSecFn:SinFunction Average cp Default NewSinF do NewSinF:set PPEventHandler:XSecFn:SinFunction Average cp Default NewSinS do NewSinS:set PPEventHandler:XSecFn:SinFunction Scaled cp Default EffPRel do EffPRel:set PPEventHandler:EffectivePartonMode Relatives cp Default DefaY7F do DefaY7F:set PPGenerator:EventHandler:YFrametest 0.7 cp DefaY7F Def01Y7 do Def01Y7:set PPEventHandler:Swinger:Lambda 0.1 cp Default DefEven do DefEven:set PPEventHandler:EventFiller:EffectiveWeights PlusEvenWeighted cp Default DefSwL4 do DefSwL4:set PPEventHandler:Swinger:Lambda 4.0 cp Default DefSw01 do DefSw01:set PPEventHandler:Swinger:Lambda 0.1 cp Default DefFSGO do DefFSGO:set FSOrdering:Generous Generous do DefFSGO:set FSOrdering:OnlyOriginal OnlyOriginalEmissions cp DefFSGO DefFSG2 do DefFSG2:set FSOrdering:Fudge 1.6 cp Default Shadows do Shadows:set PPEventHandler:EffectivePartonMode Shadows cp Default DefSing do DefSing:set PPEventHandler:FudgeME 2 do DefSing:set PPTestTune:EventHandler:EventFiller:OnlyOnce true do DefSing:set PPTestTune:EventHandler:EventFiller:SingleMother 1 cp DefSing DefComp do DefComp:set PPTestTune:EventHandler:EventFiller:CompatMode 1 cp Default Shadow8 do Shadow8:set PPEventHandler:EffectivePartonMode Shadows do Shadow8:set PPEventHandler:FudgeME 2 do Shadow8:set PPTestTune:EventHandler:EventFiller:OnlyOnce true do Shadow8:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do Shadow8:set stdEmitter:MinusOrderingMode OrderedShadow do Shadow8:set stdXSec:IntOrdering ShadowOpen cp Default Shadow9 do Shadow9:set PPEventHandler:EffectivePartonMode Shadows do Shadow9:set PPEventHandler:FudgeME 2 do Shadow9:set PPTestTune:EventHandler:EventFiller:OnlyOnce true do Shadow9:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do Shadow9:set stdEmitter:MinusOrderingMode OrderedShadow do Shadow9:set stdXSec:IntOrdering ShadowColour cp Default ShadowA do ShadowA:set PPEventHandler:EffectivePartonMode Shadows do ShadowA:set PPEventHandler:FudgeME 2 do ShadowA:set PPTestTune:EventHandler:EventFiller:OnlyOnce true do ShadowA:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowA:set stdEmitter:MinusOrderingMode UnrderedShadow do ShadowA:set stdXSec:IntOrdering ShadowColour # cp ShadowA ShadowB the former is with new setEmissionMomentum (-DDIPSY::PlusEvo) # cp ShadowA ShadowC the former with small bugfix? cp Default ShadowD do ShadowD:set PPEventHandler:EffectivePartonMode Shadows do ShadowD:set PPEventHandler:FudgeME 2 do ShadowD:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowD:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowD:set stdEmitter:MinusOrderingMode CutShadow do ShadowD:set stdXSec:IntOrdering ShadowColourMax cp Default ShadowE do ShadowE:set PPEventHandler:EffectivePartonMode Shadows do ShadowE:set PPEventHandler:FudgeME 2 do ShadowE:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowE:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowE:set stdEmitter:MinusOrderingMode CutShadow do ShadowE:set stdXSec:IntOrdering ShadowColourMax do ShadowE:set stdXSec:RMax -1.0 cp Default ShadowF do ShadowF:set PPEventHandler:EffectivePartonMode Shadows do ShadowF:set PPEventHandler:FudgeME 2 do ShadowF:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowF:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowF:set stdEmitter:MinusOrderingMode CutShadow do ShadowF:set stdXSec:IntOrdering ShadowColourMax do ShadowF:set stdXSec:SinFunction Scaled do ShadowF:set stdXSec:RMax -1.0 cp Default ShadowG do ShadowG:set PPEventHandler:EffectivePartonMode Shadows do ShadowG:set PPEventHandler:FudgeME 2 do ShadowG:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowG:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowG:set stdEmitter:MinusOrderingMode CutShadow do ShadowG:set stdXSec:IntOrdering ShadowColourMax do ShadowG:set stdXSec:PTScale 1.0 do ShadowG:set stdXSec:RMax -1.0 cp Default ShadowH do ShadowH:set PPEventHandler:EffectivePartonMode Shadows do ShadowH:set PPEventHandler:FudgeME 2 do ShadowH:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowH:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowH:set stdEmitter:MinusOrderingMode CutShadow do ShadowH:set stdXSec:IntOrdering ShadowColourMax cp Default ShadowI do ShadowI:set PPEventHandler:EffectivePartonMode Shadows do ShadowI:set PPEventHandler:FudgeME 2 # do ShadowI:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowI:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowI:set PPTestTune:EventHandler:PTScale -1 do ShadowI:set PPTestTune:EventHandler:FixedAlphaS -0.5 do ShadowI:set stdEmitter:MinusOrderingMode PtGen do ShadowI:set stdXSec:IntOrdering ShadowColourMax cp Default ShadowJ do ShadowJ:set PPEventHandler:EffectivePartonMode Shadows do ShadowJ:set PPEventHandler:FudgeME 2 do ShadowJ:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowJ:set PPTestTune:EventHandler:PTScale -1 do ShadowJ:set PPTestTune:EventHandler:FixedAlphaS -0.5 do ShadowJ:set stdEmitter:MinusOrderingMode PtGen do ShadowJ:set stdXSec:IntOrdering ShadowColourMax do ShadowJ:set stdXSec:SinFunction Scaled cp Default ShadowK do ShadowK:set PPEventHandler:EffectivePartonMode Shadows do ShadowK:set PPEventHandler:FudgeME 2 do ShadowK:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowK:set PPTestTune:EventHandler:PTScale -1 do ShadowK:set PPTestTune:EventHandler:FixedAlphaS -0.5 do ShadowK:set stdEmitter:MinusOrderingMode CutShadow do ShadowK:set stdXSec:IntOrdering ShadowColourMax do ShadowK:set stdXSec:SinFunction Scaled cp Default ShadowL do ShadowL:set PPEventHandler:EffectivePartonMode Shadows do ShadowL:set PPEventHandler:FudgeME 2 do ShadowL:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowL:set PPTestTune:EventHandler:PTScale -1 do ShadowL:set PPTestTune:EventHandler:FixedAlphaS -0.5 do ShadowL:set stdEmitter:MinusOrderingMode PtGen do ShadowL:set stdXSec:IntOrdering ShadowColourMax do ShadowL:set stdXSec:SinFunction Scaled do ShadowL:set stdEmitter:SplittingFunction FullAP cp Default ShadowM do ShadowM:set PPEventHandler:EffectivePartonMode Shadows do ShadowM:set PPEventHandler:FudgeME 2 do ShadowM:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowM:set PPTestTune:EventHandler:PTScale -1 do ShadowM:set PPTestTune:EventHandler:FixedAlphaS -0.5 do ShadowM:set stdEmitter:MinusOrderingMode PtGen do ShadowM:set stdXSec:IntOrdering ShadowColourMax do ShadowM:set stdXSec:SinFunction Scaled do ShadowM:set stdEmitter:SplittingFunction FullAP do ShadowM:set PPTestTune:EventHandler:EventFiller:OnlyOnce true cp Default ShadowN do ShadowN:set PPEventHandler:EffectivePartonMode Shadows do ShadowN:set PPEventHandler:FudgeME 2 do ShadowN:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowN:set PPTestTune:EventHandler:PTScale -1 do ShadowN:set PPTestTune:EventHandler:FixedAlphaS -0.5 do ShadowN:set stdEmitter:MinusOrderingMode PtGen do ShadowN:set stdXSec:IntOrdering ShadowColourMax do ShadowN:set stdXSec:SinFunction Scaled do ShadowN:set stdEmitter:SplittingFunction FullAP do ShadowN:set PPTestTune:EventHandler:EventFiller:OnlyOnce true cp Default ShadowO do ShadowO:set PPEventHandler:EffectivePartonMode Shadows do ShadowO:set PPEventHandler:FudgeME 2 do ShadowO:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowO:set PPTestTune:EventHandler:PTScale -1 do ShadowO:set PPTestTune:EventHandler:FixedAlphaS -0.5 do ShadowO:set stdEmitter:MinusOrderingMode PtGen do ShadowO:set stdXSec:IntOrdering ShadowColourMax do ShadowO:set stdEmitter:SplittingFunction FullAP do ShadowO:set PPTestTune:EventHandler:EventFiller:OnlyOnce true cp Default ShadowP do ShadowP:set PPEventHandler:EffectivePartonMode Shadows do ShadowP:set PPEventHandler:FudgeME 2 do ShadowP:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowP:set PPTestTune:EventHandler:PTScale -1 do ShadowP:set PPTestTune:EventHandler:FixedAlphaS -0.5 do ShadowP:set stdEmitter:MinusOrderingMode PtGen do ShadowP:set stdXSec:IntOrdering ShadowColourMax do ShadowP:set stdEmitter:SplittingFunction FullAP do ShadowP:set PPTestTune:EventHandler:EventFiller:OnlyOnce false cp Default ShadowQ do ShadowQ:set PPEventHandler:EffectivePartonMode Shadows do ShadowQ:set PPEventHandler:FudgeME 2 do ShadowQ:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowQ:set PPTestTune:EventHandler:PTScale -1 do ShadowQ:set PPTestTune:EventHandler:FixedAlphaS -0.5 do ShadowQ:set stdEmitter:MinusOrderingMode PtGenZ do ShadowQ:set stdXSec:IntOrdering ShadowColourMax do ShadowQ:set stdEmitter:SplittingFunction FullAP do ShadowQ:set PPTestTune:EventHandler:EventFiller:OnlyOnce false cp Default ShadowR do ShadowR:set PPEventHandler:EffectivePartonMode Shadows do ShadowR:set PPEventHandler:FudgeME 2 do ShadowR:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowR:set PPTestTune:EventHandler:PTScale -1 do ShadowR:set PPTestTune:EventHandler:FixedAlphaS -1.0 do ShadowR:set stdEmitter:MinusOrderingMode PtGenZ do ShadowR:set stdXSec:IntOrdering ShadowColourMax do ShadowR:set stdEmitter:SplittingFunction FullAP do ShadowR:set PPTestTune:EventHandler:EventFiller:OnlyOnce false cp Default ShadowS do ShadowS:set PPEventHandler:EffectivePartonMode Shadows do ShadowS:set PPEventHandler:FudgeME 2 do ShadowS:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowS:set PPTestTune:EventHandler:PTScale -1 do ShadowS:set PPTestTune:EventHandler:FixedAlphaS -1.0 do ShadowS:set stdEmitter:MinusOrderingMode PtGenZ do ShadowS:set stdXSec:IntOrdering ShadowColourMax do ShadowS:set stdEmitter:SplittingFunction FullAPkTsup4 do ShadowS:set PPTestTune:EventHandler:EventFiller:OnlyOnce false cp Default ShadowT do ShadowT:set PPEventHandler:EffectivePartonMode Shadows do ShadowT:set PPEventHandler:FudgeME 2 do ShadowT:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowT:set PPTestTune:EventHandler:PTScale -1 do ShadowT:set PPTestTune:EventHandler:FixedAlphaS -1.0 do ShadowT:set stdEmitter:MinusOrderingMode PtGenZ do ShadowT:set stdXSec:IntOrdering ShadowColourMax do ShadowT:set stdEmitter:SplittingFunction FullAP do ShadowT:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowT:set FSOrdering:OnlyOriginal OriginalPropagators cp Default ShadowU do ShadowU:set PPEventHandler:EffectivePartonMode Shadows do ShadowU:set PPEventHandler:FudgeME 2 do ShadowU:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowU:set PPTestTune:EventHandler:PTScale -1 do ShadowU:set PPTestTune:EventHandler:FixedAlphaS -1.0 do ShadowU:set stdEmitter:MinusOrderingMode PtGenZ do ShadowU:set stdXSec:IntOrdering ShadowColourMax do ShadowU:set stdEmitter:SplittingFunction FullAP do ShadowU:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowU:set FSOrdering:OnlyOriginal OriginalPropagators do ShadowU:set FSOrdering:Generous Generous do ShadowU:set PPTestTune:EventHandler:EventFiller:PTCut 2.0 do ShadowU:set FSOrdering:PTMin 2.0 cp Default ShadowV do ShadowV:set PPEventHandler:EffectivePartonMode Shadows do ShadowV:set PPEventHandler:FudgeME 2 do ShadowV:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowV:set PPTestTune:EventHandler:PTScale -1 do ShadowV:set PPTestTune:EventHandler:FixedAlphaS -1.0 do ShadowV:set stdEmitter:MinusOrderingMode PtGenZ do ShadowV:set stdXSec:IntOrdering ShadowColourMax do ShadowV:set stdEmitter:SplittingFunction FullAP do ShadowV:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowV:set FSOrdering:OnlyOriginal OriginalPropagators do ShadowV:set FSOrdering:Generous Normal cp Default ShadowW do ShadowW:set PPEventHandler:EffectivePartonMode Shadows do ShadowW:set PPEventHandler:FudgeME 2 do ShadowW:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowW:set PPTestTune:EventHandler:PTScale -1 do ShadowW:set PPTestTune:EventHandler:FixedAlphaS -1.0 do ShadowW:set stdEmitter:MinusOrderingMode PtGenZ do ShadowW:set stdXSec:IntOrdering ShadowColourMax do ShadowW:set stdEmitter:SplittingFunction FullAP do ShadowW:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowW:set FSOrdering:OnlyOriginal OriginalPropagators do ShadowW:set FSOrdering:Generous Generous cp Default ShadowX do ShadowX:set PPEventHandler:EffectivePartonMode Shadows do ShadowX:set PPEventHandler:FudgeME 2 do ShadowX:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowX:set PPTestTune:EventHandler:PTScale -1 do ShadowX:set PPTestTune:EventHandler:FixedAlphaS -1.0 do ShadowX:set stdEmitter:MinusOrderingMode PtGenZ do ShadowX:set stdXSec:IntOrdering ShadowColourMax do ShadowX:set stdEmitter:SplittingFunction FullAP do ShadowX:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowX:set FSOrdering:OnlyOriginal OriginalPropagators do ShadowX:set FSOrdering:Generous Generous do ShadowX:set Frag8:StringZ_aLund 0.41 do ShadowX:set Frag8:StringZ_bLund 0.46 do ShadowX:set Frag8:StringPT_sigma 0.32 do ShadowX:set Frag8:StringFlav_probQQtoQ 0.079 do ShadowX:set Frag8:StringFlav_probStoUD 0.22 do ShadowX:set AriadneCascade:LambdaQCD 0.25 cp Default ShadowY do ShadowY:set PPEventHandler:EffectivePartonMode Shadows do ShadowY:set PPEventHandler:FudgeME 2 do ShadowY:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowY:set PPTestTune:EventHandler:PTScale -1 do ShadowY:set PPTestTune:EventHandler:FixedAlphaS -1.0 do ShadowY:set stdEmitter:MinusOrderingMode PtGenZ do ShadowY:set stdXSec:IntOrdering ShadowColourMax do ShadowY:set stdEmitter:SplittingFunction FullAP do ShadowY:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowY:set FSOrdering:OnlyOriginal OriginalPropagators do ShadowY:set FSOrdering:Generous Generous do ShadowY:set Frag8:StringZ_aLund 0.42 do ShadowY:set Frag8:StringZ_bLund 0.57 do ShadowY:set Frag8:StringPT_sigma 0.3 do ShadowY:set Frag8:StringFlav_probQQtoQ 0.079 do ShadowY:set Frag8:StringFlav_probStoUD 0.22 do ShadowY:set AriadneCascade:LambdaQCD 0.28 do ShadowY:set AriadneCascade:PTCut 0.5 cp Default ShadowZ do ShadowZ:set PPEventHandler:EffectivePartonMode Shadows do ShadowZ:set PPEventHandler:FudgeME 2 do ShadowZ:set PPTestTune:EventHandler:EventFiller:SingleMother 1 do ShadowZ:set PPTestTune:EventHandler:PTScale -1 do ShadowZ:set PPTestTune:EventHandler:FixedAlphaS -1.0 do ShadowZ:set stdEmitter:MinusOrderingMode PtGenZ do ShadowZ:set stdXSec:IntOrdering ShadowColourMax do ShadowZ:set stdEmitter:SplittingFunction FullAP do ShadowZ:set PPTestTune:EventHandler:EventFiller:OnlyOnce false do ShadowZ:set FSOrdering:OnlyOriginal OriginalPropagators do ShadowZ:set FSOrdering:Generous Generous do ShadowZ:set Frag8:StringZ_aLund 0.42 do ShadowZ:set Frag8:StringZ_bLund 0.57 do ShadowZ:set Frag8:StringPT_sigma 0.3 do ShadowZ:set Frag8:StringFlav_probQQtoQ 0.079 do ShadowZ:set Frag8:StringFlav_probStoUD 0.22 do ShadowZ:set AriadneCascade:LambdaQCD 0.28 do ShadowZ:set AriadneCascade:PTCut 0.5 do ShadowZ:set Proton:Connected QQGQ cp Default Defaupt do Defaupt:set PPTestTune:EventHandler:EventFiller:PTCut 2.0 do Defaupt:set FSOrdering:PTMin 2.0 # Run for tuning SAVERUNFSXD Default PPGenerator Default PPXSecGenerator SAVERUNFSXD Defaul2 PPGenerator Defaul2 PPXSecGenerator SAVERUNFSXD DefRope PPGenerator Default PPXSecGenerator SAVERUNFSXD DefRop2 PPGenerator Defaul2 PPXSecGenerator SAVERUNFSXD Shove00 PPGenerator Shove00 PPXSecGenerator +SAVERUNFSXD Shove01 PPGenerator Shove01 PPXSecGenerator +SAVERUNFSXD Shove02 PPGenerator Shove02 PPXSecGenerator +SAVERUNFSXD Shove03 PPGenerator Shove03 PPXSecGenerator +SAVERUNFSXD Shove04 PPGenerator Shove04 PPXSecGenerator SAVERUNFSXD NoSwing PPGenerator Default PPXSecGenerator SAVERUNFSXD NewSinF PPGenerator NewSinF PPXSecGenerator SAVERUNFSXD NewSinS PPGenerator NewSinS PPXSecGenerator SAVERUNFSXD NewSing PPGenerator NewSing PPXSecGenerator SAVERUNFSXD EffPRel PPGenerator EffPRel PPXSecGenerator SAVERUNFSXD DefaY7F PPGenerator DefaY7F PPXSecGenerator SAVERUNFSXD Def01Y7 PPGenerator Def01Y7 PPXSecGenerator SAVERUNFSXD DefEven PPGenerator DefEven PPXSecGenerator SAVERUNFSXD DefSwL4 PPGenerator DefSwL4 PPXSecGenerator SAVERUNFSXD DefSw01 PPGenerator DefSw01 PPXSecGenerator SAVERUNFSXD DefFSGO PPGenerator Default PPXSecGenerator SAVERUNFSXD DefFSG2 PPGenerator Default PPXSecGenerator SAVERUNFSXD Shadows PPGenerator Shadows PPXSecGenerator SAVERUNFSXD DefSing PPGenerator DefSing PPXSecGenerator SAVERUNFSXD DefComp PPGenerator DefComp PPXSecGenerator SAVERUNFSXD Shadow8 PPGenerator Shadow8 PPXSecGenerator SAVERUNFSXD Shadow9 PPGenerator Shadow9 PPXSecGenerator SAVERUNFSXD ShadowA PPGenerator ShadowA PPXSecGenerator SAVERUNFSXD ShadowD PPGenerator ShadowD PPXSecGenerator SAVERUNFSXD Defaupt PPGenerator Defaupt PPXSecGenerator do PPGenerator:RemoveInterface /DIPSY/PPEventHandler:Emitter:PMinusOrdering do PPGenerator:AddRndInterface /DIPSY/PPEventHandler:Emitter:RMax 1 1.0 5.0 2.9 0.6 do PPXSecGenerator:RemoveInterface /DIPSY/PPEventHandler:Emitter:PMinusOrdering do PPXSecGenerator:AddRndInterface /DIPSY/PPEventHandler:Emitter:RMax 1 1.0 5.0 2.9 0.6 SAVERUNFSXD ShadowE PPGenerator ShadowE PPXSecGenerator SAVERUNFSXD ShadowF PPGenerator ShadowF PPXSecGenerator SAVERUNFSXD ShadowG PPGenerator ShadowG PPXSecGenerator do PPGenerator:RemoveInterface /DIPSY/PPEventHandler:Emitter:RMax do PPGenerator:AddRndInterface /DIPSY/PPEventHandler:BaryonSize 1 1.0 5.0 2.9 0.6 do PPXSecGenerator:RemoveInterface /DIPSY/PPEventHandler:Emitter:RMax do PPXSecGenerator:AddRndInterface /DIPSY/PPEventHandler:BaryonSize 1 1.0 5.0 2.9 0.6 SAVERUNFSXD ShadowH PPGenerator ShadowH PPXSecGenerator SAVERUNFSXD ShadowI PPGenerator ShadowI PPXSecGenerator do PPGenerator:AddRndInterface /DIPSY/PPEventHandler:Emitter:PTScale 1 1.5 2.5 1.0 0.5 do PPXSecGenerator:AddRndInterface /DIPSY/PPEventHandler:Emitter:PTScale 1 1.5 2.5 1.0 0.5 SAVERUNFSXD ShadowJ PPGenerator ShadowJ PPXSecGenerator SAVERUNFSXD ShadowK PPGenerator ShadowK PPXSecGenerator SAVERUNFSXD ShadowL PPGenerator ShadowL PPXSecGenerator SAVERUNFSXD ShadowM PPGenerator ShadowM PPXSecGenerator do PPGenerator:AddRndInterface /DIPSY/PPEventHandler:Emitter:PTScale 1 0.5 2.5 1.5 0.5 do PPXSecGenerator:AddRndInterface /DIPSY/PPEventHandler:Emitter:PTScale 1 0.5 2.5 1.5 0.5 do PPGenerator:RemoveInterface /DIPSY/PPEventHandler:RMax do PPGenerator:AddRndInterface /DIPSY/PPEventHandler:M0 100 0.5 2.0 0.8 0.6 do PPXSecGenerator:RemoveInterface /DIPSY/PPEventHandler:RMax do PPXSecGenerator:AddRndInterface /DIPSY/PPEventHandler:M0 100 0.5 2.0 0.8 0.6 SAVERUNFSXD ShadowN PPGenerator ShadowN PPXSecGenerator SAVERUNFSXD ShadowO PPGenerator ShadowO PPXSecGenerator SAVERUNFSXD ShadowP PPGenerator ShadowP PPXSecGenerator SAVERUNFSXD ShadowQ PPGenerator ShadowQ PPXSecGenerator SAVERUNFSXD ShadowR PPGenerator ShadowR PPXSecGenerator SAVERUNFSXD ShadowS PPGenerator ShadowS PPXSecGenerator SAVERUNFSXD ShadowT PPGenerator ShadowT PPXSecGenerator SAVERUNFSXD ShadowU PPGenerator ShadowU PPXSecGenerator SAVERUNFSXD ShadowV PPGenerator ShadowV PPXSecGenerator SAVERUNFSXD ShadowW PPGenerator ShadowW PPXSecGenerator SAVERUNFSXD ShadowX PPGenerator ShadowX PPXSecGenerator SAVERUNFSXD ShadowY PPGenerator ShadowY PPXSecGenerator SAVERUNFSXD ShadowZ PPGenerator ShadowZ PPXSecGenerator # testing the tunes SAVERUNTUNED Default PPTestTune SAVERUNTUNED Defaul2 PPTestTune SAVERUNTUNED DefRope PPTestTune SAVERUNTUNED DefRop2 PPTestTune SAVERUNTUNED Shove00 PPTestTune +SAVERUNTUNED Shove01 PPTestTune +SAVERUNTUNED Shove02 PPTestTune +SAVERUNTUNED Shove03 PPTestTune +SAVERUNTUNED Shove04 PPTestTune SAVERUNTUNED NewSinF PPTestTune SAVERUNTUNED NewSinS PPTestTune SAVERUNTUNED NoSwing PPTestTune SAVERUNTUNED NewSing PPTestTune SAVERUNTUNED EffPRel PPTestTune SAVERUNTUNED DefaY7F PPTestTune SAVERUNTUNED Def01Y7 PPTestTune SAVERUNTUNED DefEven PPTestTune SAVERUNTUNED DefSwL4 PPTestTune SAVERUNTUNED DefSw01 PPTestTune SAVERUNTUNED DefFSGO PPTestTune SAVERUNTUNED DefFSG2 PPTestTune SAVERUNTUNED Shadows PPTestTune SAVERUNTUNED DefSing PPTestTune SAVERUNTUNED DefComp PPTestTune SAVERUNTUNED Shadow8 PPTestTune SAVERUNTUNED Shadow9 PPTestTune SAVERUNTUNED ShadowA PPTestTune SAVERUNTUNED ShadowD PPTestTune SAVERUNTUNED ShadowE PPTestTune SAVERUNTUNED ShadowF PPTestTune SAVERUNTUNED ShadowG PPTestTune SAVERUNTUNED ShadowH PPTestTune SAVERUNTUNED ShadowI PPTestTune SAVERUNTUNED ShadowJ PPTestTune SAVERUNTUNED ShadowK PPTestTune SAVERUNTUNED ShadowL PPTestTune SAVERUNTUNED ShadowM PPTestTune SAVERUNTUNED ShadowN PPTestTune SAVERUNTUNED ShadowO PPTestTune SAVERUNTUNED ShadowP PPTestTune SAVERUNTUNED ShadowQ PPTestTune SAVERUNTUNED ShadowR PPTestTune SAVERUNTUNED ShadowS PPTestTune SAVERUNTUNED ShadowT PPTestTune SAVERUNTUNED ShadowU PPTestTune SAVERUNTUNED ShadowV PPTestTune SAVERUNTUNED ShadowW PPTestTune SAVERUNTUNED ShadowX PPTestTune SAVERUNTUNED ShadowZ PPTestTune SAVERUNTUNED Defaupt PPTestTune ##### playground ##### erase PPTestTune:DefaultObjects[0] set PPTestTune:DefaultObjects[0] Default set PPEventHandler:LambdaQCD 0.22 set PPEventHandler:RMax 3.0 set stdEmitter:PMinusOrdering 1.0 set stdEmitter:PTScale 1.0 set PPGenerator:EventHandler:PreSamples 0 # set PPGenerator:EventHandler:PreSamples 0 set PPGenerator:EventHandler:EventFiller:DebugHist 1 set PPTestTune:NumberOfEvents 10000 saverun compare PPTestTune set stdEmitter:PTScale 2 saverun compar6 PPTestTune set stdEmitter:PTScale 1 set stdEmitter:PMinusOrdering 2.0 saverun compar5 PPTestTune set stdEmitter:PMinusOrdering 1.0 set PPEventHandler:FudgeME 2 set PPTestTune:EventHandler:EventFiller:OnlyOnce true set PPTestTune:EventHandler:EventFiller:SingleMother 1 saverun compar2 PPTestTune set PPTestTune:EventHandler:EventFiller:CompatMode 1 saverun compar3 PPTestTune set PPTestTune:EventHandler:EventFiller:CompatMode 0 set PPTestTune:EventHandler:EffectivePartonMode Relatives saverun compar4 PPTestTune set PPTestTune:EventHandler:EventFiller:OnlyOnce false set PPEventHandler:FudgeME 1 set PPTestTune:EventHandler:EventFiller:SingleMother 0 set PPTestTune:EventHandler:EventFiller:CompatMode 0 set PPTestTune:EventHandler:EffectivePartonMode Shadows saverun shadows PPTestTune set PPEventHandler:FudgeME 2 set PPTestTune:EventHandler:EventFiller:OnlyOnce true set PPTestTune:EventHandler:EventFiller:SingleMother 1 saverun shadow2 PPTestTune saverun shadow3 PPTestTune set stdEmitter:MinusOrderingMode EffectiveParton saverun shadow4 PPTestTune set stdEmitter:MinusOrderingMode TrueShadow saverun shadow6 PPTestTune set stdEmitter:MinusOrderingMode OrderedShadow saverun shadow7 PPTestTune set stdXSec:IntOrdering ShadowOpen saverun shadow8 PPTestTune set stdXSec:IntOrdering ShadowColour set PPTestTune:NumberOfEvents 10000 saverun shadow9 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 2.0 set FSOrdering:PTMin 2.0 saverun shadow11 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 4.0 set FSOrdering:PTMin 4.0 saverun shadow12 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 1.0 set FSOrdering:PTMin 1.0 set stdEmitter:MinusOrderingMode UnorderedShadow saverun shadow14 PPTestTune set stdXSec:IntOrdering ShadowColourMax saverun shadow15 PPTestTune saverun shadow16 PPTestTune saverun shadow17 PPTestTune set stdEmitter:PlusInflation 2.0 saverun shadow18 PPTestTune set stdEmitter:PlusInflation 1.0 set stdEmitter:MinusOrderingMode CutShadow # erase PPTestTune:AnalysisHandlers[0] # erase PPTestTune:AnalysisHandlers[0] # erase PPTestTune:AnalysisHandlers[0] # set PPTestTune:EventHandler:CascadeHandler NULL # set PPTestTune:EventHandler:HadronizationHandler NULL # set PPTestTune:EventHandler:DecayHandler NULL # erase PPTestTune:DefaultObjects[0] saverun shadow21 PPTestTune set PPTestTune:EventHandler:EventFiller:OnlyOnce false saverun shadow23 PPTestTune set stdEmitter:SizeFactor 1.0 saverun shadow30 PPTestTune set stdEmitter:SizeFactor 2.0 # set stdEmitter:MinusOrderingMode PtGen # saverun shadow32 PPTestTune set stdEmitter:MinusOrderingMode CutShadow set stdXSec:KTPow 2.0 set stdXSec:KT0 1.0 saverun shadow29 PPTestTune set stdEmitter:SizeFactor 1.0 saverun shadow31 PPTestTune set stdEmitter:SizeFactor 2.0 set stdXSec:KTPow 0.0 set stdEmitter:PMinusOrdering 2.0 saverun shadow25 PPTestTune set stdEmitter:PMinusOrdering 1.0 set stdEmitter:PTScale 2.0 saverun shadow26 PPTestTune set stdXSec:PTScale 1 saverun shadow28 PPTestTune set stdXSec:PTScale 0 set stdXSec:SinFunction Scaled saverun shadow27 PPTestTune set stdEmitter:PTScale 1.0 set stdXSec:SinFunction Exact set PPTestTune:EventHandler:EventFiller:OnlyOnce true set PPTestTune:EventHandler:EffectivePartonMode NewShadows saverun shadow22 PPTestTune set PPTestTune:EventHandler:EventFiller:OnlyOnce false saverun shadow24 PPTestTune set PPTestTune:EventHandler:EventFiller:OnlyOnce true set PPTestTune:EventHandler:EffectivePartonMode Shadows saverun shadow23 PPTestTune set stdEmitter:PTScale 2 saverun shadow33 PPTestTune set PPTestTune:EventHandler:PTScale -1 set PPTestTune:NumberOfEvents 10000 saverun shadow34 PPTestTune set stdEmitter:MinusOrderingMode PtGen saverun shadow35 PPTestTune set stdEmitter:SplittingFunction FullAP saverun shadow36 PPTestTune set stdEmitter:MinusOrderingMode PtGenZ saverun shadow37 PPTestTune set PPTestTune:EventHandler:EventFiller:OnlyOnce false set PPTestTune:EventHandler:FixedAlphaS -0.5 set PPTestTune:EventHandler:PTScale -1 saverun shadow40 PPTestTune saverun shadow41 PPTestTune saverun shadow42 PPTestTune set stdEmitter:SplittingFunction FullAPkTsup saverun shadow43 PPTestTune set stdEmitter:SplittingFunction FullAPkTsup3 saverun shadow44 PPTestTune set stdEmitter:SplittingFunction FullAPkTsup4 saverun shadow45 PPTestTune set stdEmitter:SplittingFunction FullAPkTsup4 saverun shadow45 PPTestTune set stdEmitter:SplittingFunction FullAPkTsupm4 saverun shadow48 PPTestTune set stdEmitter:SplittingFunction FullAP set stdEmitter:PTScale 1 saverun shadow46 PPTestTune set stdEmitter:PTScale 0.5 saverun shadow47 PPTestTune set stdEmitter:PTScale 1 set stdEmitter:RMax 0.1 saverun shadow49 PPTestTune set stdEmitter:RMax 0 saverun shadow50 PPTestTune saverun shadow60 PPTestTune set FSOrdering:OnlyOriginal OriginalPropagators set FSOrdering:Generous Generous saverun shadow61 PPTestTune saverun shadow62 PPTestTune set FSOrdering:Generous Normal saverun shadow63 PPTestTune set Frag8:FragmentationScheme none set Frag8:StringZ_aLund 0.41 set Frag8:StringZ_bLund 0.46 set Frag8:StringPT_sigma 0.32 set Frag8:StringFlav_probQQtoQ 0.079 set Frag8:StringFlav_probStoUD 0.22 set AriadneCascade:LambdaQCD 0.25 saverun shadow65 PPTestTune set Frag8:StringZ_aLund 0.42 set Frag8:StringZ_bLund 0.57 set Frag8:StringPT_sigma 0.30 set Frag8:StringFlav_probQQtoQ 0.079 set Frag8:StringFlav_probStoUD 0.22 set AriadneCascade:LambdaQCD 0.28 set AriadneCascade:PTCut 0.5 saverun shadow66 PPTestTune saverun shadow67 PPTestTune set stdEmitter:MinusOrderingMode PtGenZM saverun shadow68 PPTestTune set PPTestTune:EventHandler:Frame NoFrame saverun shadow69 PPTestTune set PPTestTune:EventHandler:Frame FixedY set stdEmitter:MinusOrderingMode PtGenZ saverun shadow70 PPTestTune set Proton:Connected QQGQ saverun shadow71 PPTestTune set Proton:Connected Connected set Frag8:FragmentationScheme none set Frag8:StringZ_aLund 0.42 set Frag8:StringZ_bLund 0.40 set Frag8:StringPT_sigma 0.32 set Frag8:StringFlav_probQQtoQ 0.084 set Frag8:StringFlav_probStoUD 0.22 set AriadneCascade:LambdaQCD 0.22 set PPTestTune:EventHandler:EventFiller:PTCut 2.0 set FSOrdering:PTMin 2.0 saverun shadow64 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 1.0 set FSOrdering:PTMin 1.0 set PPEventHandler:Swinger:Lambda 1.0 set FSOrdering:Generous Restrictive set FSOrdering:OnlyOriginal AllEmissions set PPTestTune:EventHandler:EventFiller:PTCut 0.5 set FSOrdering:PTMin 0.5 saverun shadow51 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 2.0 set FSOrdering:PTMin 2.0 saverun shadow52 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 4.0 set FSOrdering:PTMin 4.0 saverun shadow53 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 10.0 set FSOrdering:PTMin 10.0 saverun shadow54 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 6.0 set FSOrdering:PTMin 6.0 saverun shadow55 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 5.0 set FSOrdering:PTMin 5.0 saverun shadow56 PPTestTune set PPTestTune:EventHandler:EventFiller:PTCut 1.0 set FSOrdering:PTMin 1.0 set stdXSec:SinFunction Scaled saverun shadow38 PPTestTune set stdXSec:SinFunction Exact set PPTestTune:EventHandler:EventFiller:OnlyOnce false saverun shadow39 PPTestTune set PPTestTune:EventHandler:EventFiller:OnlyOnce true set stdEmitter:SplittingFunction SmallX set stdEmitter:MinusOrderingMode CutShadow set PPTestTune:EventHandler:PTScale 2 set stdEmitter:PTScale 1 set stdXSec:IntOrdering ShadowColour set stdEmitter:MinusOrderingMode OrderedShadow set PPTestTune:NumberOfEvents 2 set PPGenerator:EventHandler:PreSamples 10000 saverun shadow10 PPTestTune set stdEmitter:MinusOrderingMode UnorderedShadow saverun shadow13 PPTestTune set stdXSec:IntOrdering ShadowColourMax saverun shadow19 PPTestTune set stdEmitter:PlusInflation 10.0 saverun shadow20 PPTestTune set stdEmitter:PlusInflation 1.0 set stdEmitter:MinusOrderingMode OrderedShadow set PPGenerator:EventHandler:PreSamples 0 set PPTestTune:NumberOfEvents 10000 set stdXSec:IntOrdering VeryOpen set stdEmitter:MinusOrderingMode EffectivePT saverun shadow5 PPTestTune set PPEventHandler:FudgeME 1 set PPTestTune:EventHandler:EventFiller:OnlyOnce false set PPTestTune:EventHandler:EventFiller:SingleMother 0 set PPTestTune:EventHandler:EffectivePartonMode Colours set PPTestTune:EventHandler:EventFiller:Mode NewSingle saverun compsng PPTestTune set PPEventHandler:FudgeME 2 set PPTestTune:EventHandler:EventFiller:OnlyOnce true set PPTestTune:EventHandler:EventFiller:SingleMother 1 saverun compsn2 PPTestTune set PPTestTune:EventHandler:EventFiller:CompatMode 1 saverun compsn3 PPTestTune set PPEventHandler:FudgeME 1 set PPTestTune:EventHandler:EventFiller:OnlyOnce false set PPTestTune:EventHandler:EventFiller:SingleMother 0 set PPTestTune:EventHandler:EventFiller:CompatMode 0 diff --git a/DIPSY/PPTune/PPTuneFS00.weights b/DIPSY/PPTune/PPTuneFS00.weights --- a/DIPSY/PPTune/PPTuneFS00.weights +++ b/DIPSY/PPTune/PPTuneFS00.weights @@ -1,51 +1,51 @@ # /ATLAS_2010_S8918562/d01-x01-y01 1.0 # /ATLAS_2010_S8918562/d03-x01-y01 1.0 # /ATLAS_2010_S8918562/d04-x01-y01 2.0 # /ATLAS_2010_S8918562/d05-x01-y01 2.0 /ATLAS_2010_S8918562/d06-x01-y01 12.0 /ATLAS_2010_S8918562/d07-x01-y01 12.0 # /ATLAS_2010_S8918562/d08-x01-y01 1.0 # /ATLAS_2010_S8918562/d10-x01-y01 1.0 # /ATLAS_2010_S8918562/d11-x01-y01 2.0 # /ATLAS_2010_S8918562/d12-x01-y01 2.0 /ATLAS_2010_S8918562/d13-x01-y01 12.0 /ATLAS_2010_S8918562/d14-x01-y01 12.0 # /ATLAS_2010_S8918562/d15-x01-y01:5.5:200.0 2.0 # /ATLAS_2010_S8918562/d17-x01-y01:5.5:200.0 2.0 # /ATLAS_2010_S8918562/d18-x01-y01:5.5:200.0 2.0 # /ATLAS_2010_S8918562/d19-x01-y01:5.5:200.0 2.0 /ATLAS_2010_S8918562/d20-x01-y01 10.0 /ATLAS_2010_S8918562/d21-x01-y01 10.0 /ATLAS_2010_S8918562/d22-x01-y01:5.5:200.0 1.0 /ATLAS_2010_S8918562/d23-x01-y01:5.5:200.0 1.0 /ATLAS_2010_S8918562/d24-x01-y01:5.5:200.0 2.0 /ATLAS_2010_S8918562/d25-x01-y01:5.5:200.0 2.0 /ATLAS_2010_S8918562/d26-x01-y01 2.0 /ATLAS_2010_S8918562/d27-x01-y01 2.0 /ATLAS_2010_S8918562/d28-x01-y01 2.0 /ATLAS_2010_S8918562/d29-x01-y01 2.0 /ATLAS_2010_S8918562/d30-x01-y01 2.0 /ATLAS_2010_S8918562/d31-x01-y01 2.0 /ATLAS_2010_S8918562/d32-x01-y01 1.0 /ATLAS_2010_S8918562/d33-x01-y01 1.0 /ATLAS_2010_S8918562/d34-x01-y01 1.0 /ATLAS_2010_S8918562/d35-x01-y01 1.0 /ATLAS_2010_S8918562/d36-x01-y01 1.0 /ATLAS_2010_S8918562/d37-x01-y01 1.0 -/ATLAS_2010_S8918562/d38-x01-y01 1.0 -/ATLAS_2010_S8918562/d39-x01-y01 1.0 +#NAN?# /ATLAS_2010_S8918562/d38-x01-y01 1.0 +#NAN?# /ATLAS_2010_S8918562/d39-x01-y01 1.0 /TOTALXSEC/d01-x01-y01 100.0 /TOTALXSEC/d01-x01-y02 100.0 # /TOTALXSEC/d01-x81-y01 20.0 # /TOTALXSEC/d01-x81-y02 20.0 /TOTALXSEC/d02-x01-y01 100.0 /TOTALXSEC/d02-x01-y02 100.0 # /TOTALXSEC/d02-x81-y01 20.0 # /TOTALXSEC/d02-x81-y02 20.0 /TOTALXSEC/d03-x01-y02 100.0 # /TOTALXSEC/d03-x81-y02 20.0 /TOTALXSEC/d04-x01-y01 100.0 # /TOTALXSEC/d04-x81-y01 20.0 /STAR_2008_S7869363/d01-x01-y01:5.5:200.0 1.0 # /STAR_2008_S7869363/d02-x01-y01 0.1 # /STAR_2008_S7869363/d02-x01-y02 0.1 diff --git a/DIPSY/PPTune/PPTuneFS09.weights b/DIPSY/PPTune/PPTuneFS09.weights --- a/DIPSY/PPTune/PPTuneFS09.weights +++ b/DIPSY/PPTune/PPTuneFS09.weights @@ -1,48 +1,48 @@ # /ATLAS_2010_S8918562/d01-x01-y01 1.0 # /ATLAS_2010_S8918562/d03-x01-y01 1.0 #/ATLAS_2010_S8918562/d04-x01-y01 4.0 # /ATLAS_2010_S8918562/d05-x01-y01 2.0 /ATLAS_2010_S8918562/d06-x01-y01 24.0 # /ATLAS_2010_S8918562/d07-x01-y01 6.0 # /ATLAS_2010_S8918562/d08-x01-y01 1.0 # /ATLAS_2010_S8918562/d10-x01-y01 1.0 #/ATLAS_2010_S8918562/d11-x01-y01 4.0 # /ATLAS_2010_S8918562/d12-x01-y01 2.0 /ATLAS_2010_S8918562/d13-x01-y01 24.0 # /ATLAS_2010_S8918562/d14-x01-y01 6.0 # /ATLAS_2010_S8918562/d15-x01-y01:5.5:200.0 4.0 # /ATLAS_2010_S8918562/d17-x01-y01 1.0 # /ATLAS_2010_S8918562/d18-x01-y01:5.5:200.0 4.0 # /ATLAS_2010_S8918562/d19-x01-y01 2.0 /ATLAS_2010_S8918562/d20-x01-y01 20.0 # /ATLAS_2010_S8918562/d21-x01-y01 6.0 /ATLAS_2010_S8918562/d22-x01-y01:5.5:200.0 2.0 # /ATLAS_2010_S8918562/d23-x01-y01 1.0 /ATLAS_2010_S8918562/d24-x01-y01:5.5:200.0 4.0 # /ATLAS_2010_S8918562/d25-x01-y01 2.0 /ATLAS_2010_S8918562/d26-x01-y01 4.0 # /ATLAS_2010_S8918562/d27-x01-y01 2.0 /ATLAS_2010_S8918562/d28-x01-y01 4.0 # /ATLAS_2010_S8918562/d29-x01-y01 1.0 /ATLAS_2010_S8918562/d30-x01-y01 4.0 # /ATLAS_2010_S8918562/d31-x01-y01 2.0 /ATLAS_2010_S8918562/d32-x01-y01 2.0 # /ATLAS_2010_S8918562/d33-x01-y01 1.0 /ATLAS_2010_S8918562/d34-x01-y01 2.0 # /ATLAS_2010_S8918562/d35-x01-y01 1.0 /ATLAS_2010_S8918562/d36-x01-y01 2.0 # /ATLAS_2010_S8918562/d37-x01-y01 1.0 -/ATLAS_2010_S8918562/d38-x01-y01 2.0 +#NAN?# /ATLAS_2010_S8918562/d38-x01-y01 2.0 # /ATLAS_2010_S8918562/d39-x01-y01 1.0 /TOTALXSEC/d01-x01-y01 100.0 /TOTALXSEC/d01-x01-y02 100.0 # /TOTALXSEC/d01-x81-y01 20.0 # /TOTALXSEC/d01-x81-y02 20.0 /TOTALXSEC/d02-x01-y01 100.0 /TOTALXSEC/d02-x01-y02 100.0 # /TOTALXSEC/d02-x81-y01 20.0 # /TOTALXSEC/d02-x81-y02 20.0 /TOTALXSEC/d03-x01-y02 100.0 # /TOTALXSEC/d03-x81-y02 20.0 /TOTALXSEC/d04-x01-y01 100.0 # /TOTALXSEC/d04-x81-y01 20.0 diff --git a/DIPSY/PPTune/PPTuneFS70.weights b/DIPSY/PPTune/PPTuneFS70.weights --- a/DIPSY/PPTune/PPTuneFS70.weights +++ b/DIPSY/PPTune/PPTuneFS70.weights @@ -1,48 +1,48 @@ # /ATLAS_2010_S8918562/d01-x01-y01 1.0 # /ATLAS_2010_S8918562/d03-x01-y01 1.0 # /ATLAS_2010_S8918562/d04-x01-y01 2.0 # /ATLAS_2010_S8918562/d05-x01-y01 4.0 # /ATLAS_2010_S8918562/d06-x01-y01 6.0 /ATLAS_2010_S8918562/d07-x01-y01 24.0 # /ATLAS_2010_S8918562/d08-x01-y01 1.0 # /ATLAS_2010_S8918562/d10-x01-y01 1.0 # /ATLAS_2010_S8918562/d11-x01-y01 2.0 # /ATLAS_2010_S8918562/d12-x01-y01 4.0 # /ATLAS_2010_S8918562/d13-x01-y01 6.0 /ATLAS_2010_S8918562/d14-x01-y01 24.0 # /ATLAS_2010_S8918562/d15-x01-y01 1.0 #/ATLAS_2010_S8918562/d17-x01-y01:5.5:200.0 4.0 # /ATLAS_2010_S8918562/d18-x01-y01 2.0 # /ATLAS_2010_S8918562/d19-x01-y01:5.5:200.0 4.0 # /ATLAS_2010_S8918562/d20-x01-y01 6.0 /ATLAS_2010_S8918562/d21-x01-y01 20.0 # /ATLAS_2010_S8918562/d22-x01-y01 1.0 /ATLAS_2010_S8918562/d23-x01-y01:5.5:200.0 2.0 # /ATLAS_2010_S8918562/d24-x01-y01 2.0 /ATLAS_2010_S8918562/d25-x01-y01:5.5:200.0 4.0 # /ATLAS_2010_S8918562/d26-x01-y01 2.0 /ATLAS_2010_S8918562/d27-x01-y01 4.0 # /ATLAS_2010_S8918562/d28-x01-y01 1.0 /ATLAS_2010_S8918562/d29-x01-y01 4.0 # /ATLAS_2010_S8918562/d30-x01-y01 2.0 /ATLAS_2010_S8918562/d31-x01-y01 4.0 # /ATLAS_2010_S8918562/d32-x01-y01 1.0 /ATLAS_2010_S8918562/d33-x01-y01 2.0 # /ATLAS_2010_S8918562/d34-x01-y01 1.0 /ATLAS_2010_S8918562/d35-x01-y01 2.0 # /ATLAS_2010_S8918562/d36-x01-y01 1.0 /ATLAS_2010_S8918562/d37-x01-y01 2.0 # /ATLAS_2010_S8918562/d38-x01-y01 1.0 -/ATLAS_2010_S8918562/d39-x01-y01 2.0 +#NAN?# /ATLAS_2010_S8918562/d39-x01-y01 2.0 /TOTALXSEC/d01-x01-y01 100.0 /TOTALXSEC/d01-x01-y02 100.0 # /TOTALXSEC/d01-x81-y01 20.0 # /TOTALXSEC/d01-x81-y02 20.0 /TOTALXSEC/d02-x01-y01 100.0 /TOTALXSEC/d02-x01-y02 100.0 # /TOTALXSEC/d02-x81-y01 20.0 # /TOTALXSEC/d02-x81-y02 20.0 /TOTALXSEC/d03-x01-y02 100.0 # /TOTALXSEC/d03-x81-y02 20.0 /TOTALXSEC/d04-x01-y01 100.0 # /TOTALXSEC/d04-x81-y01 20.0 diff --git a/DIPSY/VectorMesonBase.cc b/DIPSY/VectorMesonBase.cc --- a/DIPSY/VectorMesonBase.cc +++ b/DIPSY/VectorMesonBase.cc @@ -1,73 +1,73 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the VectorMesonBase class. // #include "VectorMesonBase.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/ParVector.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/PDT/ParticleData.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace DIPSY; VectorMesonBase::~VectorMesonBase() {} Energy2 VectorMesonBase::psi2(InvEnergy r, double z) { Energy2 sum = 0.0*GeV2; for ( int f = 1; f <= abs(maxFlav()); ++f ) sum += sqr(psi(0, 1, 1, f, r, z)) + sqr(psi(1, 1, -1, f, r, z)) + sqr(psi(1, -1, 1, f, r, z)) + sqr(psi(1, 1, 1, f, r, z)); return sum; } -void VectorMesonBase::doinit() throw(InitException) { +void VectorMesonBase::doinit() { WaveFunction::doinit(); for ( int f = 1; f <= abs(maxFlav()); ++f ) if ( qmass[f] < 0.0*GeV ) qmass[f] = generator()->getParticleData(f)->mass(); } void VectorMesonBase::persistentOutput(PersistentOStream & os) const { os << theMaxFlav << ounit(qmass, GeV); } void VectorMesonBase::persistentInput(PersistentIStream & is, int) { is >> theMaxFlav >> iunit(qmass, GeV); } // Static variable needed for the type description system in ThePEG. #include "ThePEG/Utilities/DescribeClass.h" DescribeAbstractClass describeDIPSYVectorMesonBase("DIPSY::VectorMesonBase", "libAriadne5.so libDIPSY.so"); void VectorMesonBase::Init() { static ClassDocumentation documentation ("The VectorMesonBase class inherits from WaveFunction and is the " "base class of all vector meson wave functions. It includes abstract " "functions for different polarization and helicity components."); static Parameter interfaceMaxFlav ("MaxFlav", "The maxumim number of flavours considered. If negative only the " "corresponding flavour will be considered.", &VectorMesonBase::theMaxFlav, 4, -6, 6, true, false, Interface::limited); static ParVector interfaceQuarkMasses ("QuarkMasses", "The quark masses to be used (zero'th component is always ignored). " "If negative, the value in the default corresponding ParticleData " "object is used instead.", &VectorMesonBase::qmass, GeV, 7, -1.0*GeV, 0*GeV, 0*GeV, true, false, Interface::nolimits); } diff --git a/DIPSY/VectorMesonBase.h b/DIPSY/VectorMesonBase.h --- a/DIPSY/VectorMesonBase.h +++ b/DIPSY/VectorMesonBase.h @@ -1,164 +1,164 @@ // -*- C++ -*- #ifndef DIPSY_VectorMesonBase_H #define DIPSY_VectorMesonBase_H // // This is the declaration of the VectorMesonBase class. // #include "Ariadne/DIPSY/WaveFunction.h" namespace DIPSY { using namespace ThePEG; /** * The VectorMesonBase class inherits from WaveFunction and is the * base class of all vector meson wave functions. It includes abstract * functions for different polarization and helicity components. * * @see \ref VectorMesonBaseInterfaces "The interfaces" * defined for VectorMesonBase. */ class VectorMesonBase: public WaveFunction { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ inline VectorMesonBase() : theMaxFlav(4), qmass(7, -1.0*GeV) {} /** * The copy constructor. */ inline VectorMesonBase(const VectorMesonBase & x) : WaveFunction(x), theMaxFlav(x.theMaxFlav), qmass(x.qmass) {} /** * The destructor. */ virtual ~VectorMesonBase(); //@} public: /** @name Abstract functions for different wave function components. */ //@{ /** * Return (the absolute value of) the wave function for the given * polarization \a pol, quark and antiquark helicities, \a h and \a * hbar, quark flavour \a flav, energy fraction \a z and transverse * size \a r. */ virtual Energy psi(int pol, int h, int hbar, int flav, InvEnergy r, double z) = 0; /** * Return the square of the wavefunction summed over flavours and * helicities. */ virtual Energy2 psi2(InvEnergy r, double z); //@} public: /** @name Simple access functions. */ //@{ /** * Get the maxumim number of flavours considered. If negative only * the corresponding flavour will be considered. */ inline int maxFlav() const { return theMaxFlav; } //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description * system before the main function starts or when this class is * dynamically loaded. */ static void Init(); // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ - virtual void doinit() throw(InitException); + virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ inline virtual void doinitrun() { WaveFunction::doinitrun(); } /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ inline virtual void dofinish() { WaveFunction::dofinish(); } //@} private: /** * The maxumim number of flavours considered. If negative only the * corresponding flavour will be considered. */ int theMaxFlav; protected: /** * The quark masses to be used (zero'th component is always ignored). */ vector qmass; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ VectorMesonBase & operator=(const VectorMesonBase &); }; } #endif /* DIPSY_VectorMesonBase_H */ diff --git a/DIPSY/runThePEG.tags b/DIPSY/runThePEG.tags --- a/DIPSY/runThePEG.tags +++ b/DIPSY/runThePEG.tags @@ -1,24 +1,25 @@ 00..: -N 1 --tag=-%t --seed %R TestOO.run R0..: -N 200 --tag=-%t --seed %R RHIC.run R1..: -N 100 --tag=-%t --seed %R RHIC.run L0..: -N 10 --tag=-%t --seed %R LHCPbPb.run Lb..: -N 10 --tag=-%t --seed %R LHCPbPb.run RFST: --tag=-%t RHICcentral.run RFSt: --tag=-%t RHICAAc.run LFST: --tag=-%t LHCppc.run LFSt: --tag=-%t LHCppC.run TuneFSS09: --tag=-%t Test5ppFS09swing.run TuneFSS70: --tag=-%t Test5ppFS70swing.run TuneFSS092: --tag=-%t Test5ppFS09sw2.run TuneFSS702: --tag=-%t Test5ppFS70sw2.run LHCPbPb.: -DDIPSY::TimeSteps %t.run TevaSD(..): --tag=%t --seed %R TevaSD.run TevaSD(.): --tag=%t --seed %R TevaSD.run LHCpPbTest41Pb(..): --tag=%t --seed %R LHCpPbTest41Pb.run (.+)(%\d+): --tag=%2 --seed %R %1.run (.+)__(.+): --tag=-%2 %1.run (.+)_(.*): --tag=#%2 %1.run +(.+)%_(.*): --tag=#%2 --seed %R %1.run .+\.run: %t .+: %t.run diff --git a/DipoleCascade/CascadeHandler.cc b/DipoleCascade/CascadeHandler.cc --- a/DipoleCascade/CascadeHandler.cc +++ b/DipoleCascade/CascadeHandler.cc @@ -1,460 +1,460 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the CascadeHandler class. // #include "CascadeHandler.h" #include "MECorrBase.h" #include "ReweightBase.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/EventRecord/Collision.h" #include "ThePEG/EventRecord/SubProcess.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Handlers/EventHandler.h" #include "ThePEG/Handlers/Hint.h" #include "ThePEG/Handlers/XComb.h" #include "ThePEG/Utilities/UtilityBase.h" #include "ThePEG/Cuts/Cuts.h" #include "Ariadne/DipoleCascade/DipoleState.h" #include "ThePEG/Utilities/EnumIO.h" #include "ThePEG/Utilities/Current.h" #include "ThePEG/Repository/EventGenerator.h" #ifdef ThePEG_TEMPLATES_IN_CC_FILE // #include "CascadeHandler.tcc" #endif #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" namespace Ariadne { CascadeHandler::CascadeHandler() : theRunningCoupling(simpleRunning), theAlpha0(0.2), theLambdaQCD(0.22*GeV), thePTCut(0.6*GeV), theAlphaEM0(1.0/137.0), thePTCutEM(0.6*GeV), theNCol(8), theNFlav(5), thePhotonEmissions(false), theSoftMu(0.6*GeV), theSoftAlpha(1.0), theHardAlpha(-1.0), theBeta(2.0), theMaxEmissions(0) {} CascadeHandler::CascadeHandler(const CascadeHandler & x) : ThePEG::CascadeHandler(x), theRunningCoupling(x.theRunningCoupling), theAlpha0(x.theAlpha0), theLambdaQCD(x.theLambdaQCD), theInternalAlphaS(x.theInternalAlphaS), thePTCut(x.thePTCut), theAlphaEM0(x.theAlphaEM0), thePTCutEM(x.thePTCutEM), theNCol(x.theNCol), theNFlav(x.theNFlav), thePhotonEmissions(x.thePhotonEmissions), theSoftMu(x.theSoftMu), theSoftAlpha(x.theSoftAlpha), theHardAlpha(x.theHardAlpha), theBeta(x.theBeta), theReweighters(x.theReweighters), theMECorrectors(x.theMECorrectors), theMaxEmissions(x.theMaxEmissions) {} CascadeHandler::~CascadeHandler() {} bool CascadeHandler::preInitialize() const { if ( ThePEG::CascadeHandler::preInitialize() ) return true; return runningCoupling() == internalRunning && !internalAlphaS(); } -void CascadeHandler::doinit() throw(InitException) { +void CascadeHandler::doinit() { ThePEG::CascadeHandler::doinit(); if ( runningCoupling() != internalRunning || internalAlphaS() ) return; theInternalAlphaS = dynamic_ptr_cast::pointer> (generator()->preinitCreate("ThePEG::O1AlphaS", fullName() + "/AlphaS", "O1AlphaS.so")); ostringstream os; os << lambdaQCD()/GeV; generator()->preinitInterface(theInternalAlphaS, "LambdaQCD", "set", os.str()); generator()->preinitInterface(theInternalAlphaS, "LambdaFlav", "set", "5"); theInternalAlphaS->update(); } void CascadeHandler::cascade() { Current current(this); LorentzRotation rot; DipoleStatePtr state; tSubProPtr sub; tPVector final; Energy2 pt2max; Energy2 pt2min = sqr(pTCut()); bool perf = false; int emnbr = 0; // Check if the state has already been generated in reweightCKKW if ( theCKKWMap.count(lastXCombPtr()) ){ CKKWState ckkw = theCKKWMap[lastXCombPtr()]; sub = subProcess(); state = ckkw.state; rot = ckkw.rotation; pt2max = ckkw.pt2; while ( emnbr == 0 && ( pt2max = state->select(pt2min, pt2max) ) > pt2min ) { DipoleState::TranslationMap trans; DipoleStatePtr newstate = state->preclone(trans); if ( state->perform() ) { if(! ckkw.maxMult && passCuts(state)){ theCKKWMap.clear(); throw Veto(); } perf = true; emnbr++; } else { newstate->postclone(trans); state = newstate; state->selected()->touch(); } } } else { state = new_ptr(DipoleState(this)); Energy2 stot = 0.0*GeV2; tCollPtr coll = eventHandler()->currentCollision(); sub = coll->primarySubProcess(); if ( sub->decayed() ) sub = tSubProPtr(); // Decide whether we are cascadeing a whole sub-process or if we // only need to deal with final-state shower. if ( ( hint().tagged() || !sub ) && !tagged().empty() ) { final = tagged(); } else if ( sub ) { rot = state->init(sub); stot = state->sTot(); } else return; if ( !final.empty() ) { rot = Utilities::boostToCM(final.begin(), final.end()); state->init(final); stot = Utilities::sumMomentum(final.begin(), final.end()).m2(); } pt2max = stot/4.0; } theCKKWMap.clear(); while ( ( pt2max = state->select(pt2min, pt2max) ) > pt2min && ( maxEmissions() == 0 || emnbr < maxEmissions() ) ) { DipoleState::TranslationMap trans; DipoleStatePtr newstate = state->preclone(trans); if ( state->perform() ) { perf = true; emnbr++; } else { newstate->postclone(trans); state = newstate; state->selected()->touch(); } if(! state->checkIntegrety()){ throw IntegretyException() << "Ariadne::CascadeHandler::cascade " << "The dipole state is not self consistant." << Exception::eventerror; } } rot.invert(); if ( final.empty() ) { if ( perf ) state->fill(sub, rot, newStep()); else sub->transform(rot); sub->decayed(true); } else { Utilities::transform(final.begin(), final.end(), rot); if ( perf ) state->fill(final, rot, newStep()); } } double CascadeHandler::reweightCKKW(int minMult, int maxMult){ if(minMult == maxMult){ return 1.0; } CKKWState ckkw; ckkw.state = new_ptr(DipoleState(this)); tXCPtr lastXC = lastXCombPtr(); int outgoing = lastXC->subProcess()->outgoing().size(); if(outgoing < minMult || outgoing > maxMult){ throw CKKWMultiplicityException() << "Ariadne::CascadeHandler::reweightCKKW " << "Number of outgoing particles out of range." << Exception::eventerror; } int steps = outgoing - minMult; ckkw.maxMult = (outgoing == maxMult); ckkw.rotation = ckkw.state->init(lastXC->subProcess()); if(! ckkw.state->constructHistory(steps)){ return 0.0; } double weight = ckkw.state->couplingProduct(steps) / pow(lastXC->lastAlphaS(), steps) * ckkw.state->PDFRatioProduct(steps); ckkw.pt2 = ckkw.state->constructedPT2(); if(ckkw.state->sudakovVeto(steps)){ return 0.0; } theCKKWMap[lastXC] = ckkw; return weight; } bool CascadeHandler::passCuts(tcDipoleStatePtr state){ tCutsPtr cuts = lastCutsPtr(); Lorentz5Momentum ph = state->hardSubSys().momentum(); cuts->initSubProcess(ph.mass2(), ph.rapidity()); tcPDVector pdata; vector< LorentzMomentum > p; typedef HardSubSys::PartonSet PartonSet; const PartonSet & active = state->hardSubSys().active(); const PartonSet & produced = state->hardSubSys().produced(); for(PartonSet::const_iterator it = active.begin(); it != active.end(); it++){ pdata.push_back((*it)->dataPtr()); p.push_back((*it)->momentum()); } for(PartonSet::const_iterator it = produced.begin(); it != produced.end(); it++){ pdata.push_back((*it)->dataPtr()); p.push_back((*it)->momentum()); } LorentzRotation R(0.0, 0.0, - ph.z()/ph.e()); Utilities::transform(p, R); return cuts->passCuts(pdata, p, state->particles().first->dataPtr(), state->particles().second->dataPtr()); } void CascadeHandler::persistentOutput(PersistentOStream & os) const { os << oenum(theRunningCoupling) << theAlpha0 << ounit(theLambdaQCD, GeV) << theInternalAlphaS << ounit(thePTCut, GeV) << theAlphaEM0 << ounit(thePTCutEM, GeV) << theNCol << theNFlav << thePhotonEmissions << ounit(theSoftMu, GeV) << theSoftAlpha << theHardAlpha << theBeta << theMECorrectors << theReweighters << theMaxEmissions; } void CascadeHandler::persistentInput(PersistentIStream & is, int) { is >> ienum(theRunningCoupling) >> theAlpha0 >> iunit(theLambdaQCD, GeV) >> theInternalAlphaS >> iunit(thePTCut, GeV) >> theAlphaEM0 >> iunit(thePTCutEM, GeV) >> theNCol >> theNFlav >> thePhotonEmissions >> iunit(theSoftMu, GeV) >> theSoftAlpha >> theHardAlpha >> theBeta >> theMECorrectors >> theReweighters >> theMaxEmissions; } ClassDescription CascadeHandler::initCascadeHandler; // Definition of the static class description member. Energy CascadeHandler::minPTCut() const { return ( runningCoupling() == simpleRunning || ( runningCoupling() == internalRunning && !theInternalAlphaS ) )? lambdaQCD(): 0.0*GeV; } Energy CascadeHandler::maxLambdaQCD() const { return ( runningCoupling() == simpleRunning || ( runningCoupling() == internalRunning && !theInternalAlphaS ) )? pTCut(): Constants::MaxEnergy; } void CascadeHandler::Init() { static ClassDocumentation documentation ("The Ariadne::CascadeHandler class administers the Ariadne dipole " "cascade.", "Parton cascades performed by Ariadne\\cite{Lav05} according to the " "Dipole Cascade Model\\cite{Gustafson:1986db,Gustafson:1988rq," "Andersson:1989gp,Andersson:1990ki}.", "\\bibitem{Lav05}" "Nils Lavesson and Leif L\\\"onnblad, Preprint in preparation.\n" "\\bibitem{Gustafson:1986db}" "G\\\"osta Gustafson, Phys.~Lett.~{\\bf B175} (1986) 453.\n" "\\bibitem{Gustafson:1988rq}" "G\\\"osta Gustafson and Ulf Pettersson, " "Nucl.~Phys.~{\\bf B306} (1988) 746.\n" "\\bibitem{Andersson:1989gp}" "Bo Andersson, et al., Z.~Phys.~{\\bf C43} (1989) 625.\n" "\\bibitem{Andersson:1990ki}" "Bo Andersson, et al., Nucl.~Phys.~{\\bf B339} (1990) 393."); static Switch interfaceRunningCoupling ("RunningCoupling", "Strategy for handling \\f$\\alpha_S\\f$.", &CascadeHandler::theRunningCoupling, simpleRunning, true, false); static SwitchOption interfaceRunningCouplingRunning (interfaceRunningCoupling, "Running", "Use a one loop running coupling with \\f$\\Lambda_{QCD}\\f$ given " "by LambdaQCD.", simpleRunning); static SwitchOption interfaceRunningCouplingConstant (interfaceRunningCoupling, "Constant", "Use a constant coupling given by Alpha0.", noRunning); static SwitchOption interfaceRunningCouplingExternal (interfaceRunningCoupling, "External", "Use whatever coupling is specified by the current StandardModelBase " "object.", externalRunning); static Parameter interfaceAlpha0 ("Alpha0", "The constant \\f$\\alpha_S\\f$ to use if " "RunningCoupling is set to Constant.", &CascadeHandler::theAlpha0, 0.2, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfaceAlphaEM0 ("AlphaEM0", "The constant \\f$\\alpha_{EM}\\f$ to use. If zero, use whatever " "is specified in the current StandardModelBase object.", &CascadeHandler::theAlphaEM0, 1.0/137.0, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfaceLambdaQCD ("LambdaQCD", "The \\f$\\Lambda_{QCD}\\f$ to use in the one loop running " "\\f$\\alpha_S\\f$ if RunningCoupling " "is set to Running.", &CascadeHandler::theLambdaQCD, GeV, 0.22*GeV, 0.0*GeV, Constants::MaxEnergy, true, false, Interface::limited, 0, 0, 0, &CascadeHandler::maxLambdaQCD, 0); static Parameter interfacePTCut ("PTCut", "The cutoff in invariant transverse momentum for QCD emissions.", &CascadeHandler::thePTCut, GeV, 0.6*GeV, 0.0*GeV, 0*GeV, true, false, Interface::lowerlim, 0, 0, &CascadeHandler::minPTCut, 0, 0); static Parameter interfacePTCutEM ("PTCutEM", "The cutoff in invariant transverse momentum for QED emissions.", &CascadeHandler::thePTCutEM, GeV, 0.6*GeV, 0.0*GeV, 0*GeV, true, false, Interface::lowerlim); static Parameter interfaceDipoleColours ("DipoleColours", "The number of differently coloured dipoles possible. This should " "normally be 8, but may be varied to check the effects of colour " "reconnections.", &CascadeHandler::theNCol, 8, 3, 0, true, false, Interface::lowerlim); static Parameter interfaceNFlav ("NFlav", "The number of possible flavours in a \f$g\to q\bar{q}\f$ splitting.", &CascadeHandler::theNFlav, 5, 0, 8, true, false, Interface::lowerlim); static Switch interfacePhotonEmissions ("PhotonEmissions", "Switches photon emission in the cascade on and off.", &CascadeHandler::thePhotonEmissions, false, true, false); static SwitchOption interfacePhotonEmissionsOn (interfacePhotonEmissions, "On", "Switch photon emission on", true); static SwitchOption interfacePhotonEmissionsOff (interfacePhotonEmissions, "Off", "Switch photon emission off.", false); static Parameter interfaceSoftMu ("SoftMu", "The inverse extension of a hadron remnant used in the soft " "suppression mechanism. See also SoftAlphs and " "Beta", &CascadeHandler::theSoftMu, GeV, 0.6*GeV, 0.0*GeV, 0*GeV, true, false, Interface::lowerlim); static Parameter interfaceSoftAlpha ("SoftAlpha", "The dimension of the extension of a hadron remnant used in the " "soft-suppression mechanism. See also SoftMu " "and Beta.", &CascadeHandler::theSoftAlpha, 1.0, 0.0, 0, true, false, Interface::lowerlim); static Parameter interfaceHardAlpha ("HardAlpha", "The dimension of the extension of a hard remnant used in the " "soft-suppression mechanism for radiation off a scattered quark in " "DIS at small \\f$Q^2\\f$. If set negative, the value of " "SoftAlpha will be used instead. See also " "Beta.", &CascadeHandler::theHardAlpha, -1.0, -1.0, 0, true, false, Interface::lowerlim); static Parameter interfaceBeta ("Beta", "The power in the suppression of radiation from extended dipoles. " "The original soft suppression model used a sharp cutoff in the " "transverse-momentum--rapidity space of an emitted gluon. This parameter " "is used to allow emissions with larger transverse momentum according to " "\\f$P(p_\\perp^2>p_{\\perp cut}^2=" "\\left(\\frac{p_{\\perp cut}^2}{p_\\perp^2}\\right)^\\beta\\f$. if " "negative, the sharp cutoff is retained.", &CascadeHandler::theBeta, 2.0, -1.0, 0, true, false, Interface::lowerlim); static RefVector interfaceMECorrectors ("MECorrectors", "A vector of objects implementing leading-order matrix-element " "corrections of basic dipole emissions. For each initial dipole " "in a cascade, each of the object in this vector will be tried in " "turn, and the first object to claim to be able to handle the " "correction is chosen.", &CascadeHandler::theMECorrectors, -1, true, false, true, false, false); static RefVector interfaceReweighters ("Reweighters", "A vector of objects implementing reweightings of basic dipole " "emissions. Each dipole emission will be reweighted.", &CascadeHandler::theReweighters, -1, true, false, true, false, false); static Parameter interfaceMaxEmissions ("MaxEmissions", "This number specifies the maximum number of emissions from the " "cascade. If it is set to zero an unlimited number is allowed. " "This parameter should only be used for debugging purposes.", &CascadeHandler::theMaxEmissions, 0, 0, 0, true, false, Interface::lowerlim); static Reference interfaceInternalAlphaS ("InternalAlphaS", "An internal AlphaSBase object to be used if " "RunningCoupling is set to InternalRunning. " "If no such object is given, A O1AlphaS object will be created and " "assigned in the initialization with LambdaQCD " "used as lambda for five flavours.", &CascadeHandler::theInternalAlphaS, true, false, true, true, false); interfacePTCut.rank(10); interfaceLambdaQCD.rank(9); interfaceNFlav.rank(8); interfaceSoftMu.rank(7); interfaceSoftAlpha.rank(6); interfaceHardAlpha.rank(5); interfaceBeta.rank(4); interfaceMECorrectors.rank(2); } } diff --git a/DipoleCascade/CascadeHandler.h b/DipoleCascade/CascadeHandler.h --- a/DipoleCascade/CascadeHandler.h +++ b/DipoleCascade/CascadeHandler.h @@ -1,495 +1,494 @@ // -*- C++ -*- #ifndef ARIADNE_CascadeHandler_H #define ARIADNE_CascadeHandler_H // // This is the declaration of the CascadeHandler class. // #include "Ariadne/Config/Ariadne.h" #include "ThePEG/Handlers/CascadeHandler.h" #include "ThePEG/Utilities/Triplet.h" #include "ThePEG/StandardModel/AlphaSBase.h" #include "CascadeHandler.fh" #include "MECorrBase.fh" #include "ReweightBase.fh" #include "DipoleState.fh" namespace Ariadne { using namespace ThePEG; /** * The CascadeHandler class inherits form the ThePEG::CascadeHandler * base class and implements the Dipole Cascade Model for partonic * cascades. * * @see \ref CascadeHandlerInterfaces "The interfaces" * defined for CascadeHandler. */ class CascadeHandler: public ThePEG::CascadeHandler { public: /** * A vector of matrix element correction objects. */ typedef vector MECVector; /** * Enum different options for running \f$\alpha_s\f$. */ enum RunningOption { externalRunning = -1, /**< Use the \f$\alpha_s\f$ specified in the current StandardModel object. */ noRunning = 0, /**< Use a fixed \f$\alpha_s\f$ specified by alpha0(). */ simpleRunning = 1, /**< Use simple leading order running with \f$\Lambda_{QCD}\f$ given by lambdaQCD() */ internalRunning = 2 /**< Use internal AlphaSBase object in theInternalAlphaS for the running. */ }; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ CascadeHandler(); /** * The copy constructor. */ CascadeHandler(const CascadeHandler &); /** * The destructor. */ virtual ~CascadeHandler(); //@} public: /** * The main function to be overwritten by sub-classes. It is called * by handle() after storing some information which is then * available through simple access functions. */ virtual void cascade(); /** * The CascadeHandler can be used inside the process generation to do * so-called CKKW reweighting of the hard sub-process. In this case * this function is called after information about the sub-process is * made available through the LastXCombInfo base class. Only the * function belonging to the primary CascadeHandler for the event to * be generated is called. This default implementation of the function * simply return one. The current sub-process is mixed together with * other processes with a multiplicity of outgoing particles between * \a minMult and \a maxMult. * @throws CKKWMultiplicityException if the minMult > maxMult or if * the number of outgoing particle is outside the specified range. */ virtual double reweightCKKW(int minMult, int maxMult); /** * Check if the particles in the dipole state passes the cuts from * lastXComb. */ bool passCuts(tcDipoleStatePtr state); public: /** @name Functions relating to the running coupling. */ //@{ /** * Strategy for \f$\alpha_S\f$. 0 means constant a constant * \f$\alpha_S\f$ with a value given by alpha0(). 1 means a leading * order running \f$\alpha_S\f$ with a \f$\Lambda_{QCD}\f$ given by * lambdaQCD(). -1 means take whatever is specified in the current * StandardModelBase object. */ inline RunningOption runningCoupling() const; /** * The constant \f$\alpha_S\f$ to be used if runningCoupling() is 0. */ inline double alpha0() const; /** * The \f$\Lambda_{QCD}\f$ to use in the one loop running * \f$\alpha_S\f$ if runningCoupling is 1 */ inline Energy lambdaQCD() const; /** * An internal \f$\alpha_S\f$ object to be used if runningCoupling() * is internalRunning. */ inline Ptr::const_pointer internalAlphaS() const; /** * The constant \f$\alpha_{EM}\f$ to be used. If zero, use whatever * is specified in the current StandardModelBase object. */ inline double alphaEM0() const; /** * The number of different colour indices available to dipoles. */ inline int nCol() const; /** * The number of possible flavours in a \f$g\to q\bar{q}\f$ splitting. */ inline int nFlav() const; //@} /** * Check if photon emission are switched on or off. */ inline bool photonEmissions() const; public: /** * The cutoff in invariant transverse momentum for QCD emissions. */ inline Energy pTCut() const; /** * The cutoff in invariant transverse momentum for QED emissions. */ inline Energy pTCutEM() const; /** * The inverse extension of a hadron remnant. */ inline Energy softMu() const; /** * The dimension assumed for the extension of a hadron remnant. */ inline double softAlpha() const; /** * The dimension assumed for the extension of a perturbative remnant. */ inline double hardAlpha() const; /** * The power in the suppression of radiation from extended dipoles. */ inline double beta() const; /** * Return the vector of available reweighting objects. */ inline const vector & reweighters() const { return theReweighters; } /** * Return the vector of available matrix element reweighting objects. */ inline const MECVector & MECorrectors() const; /** * The maximum number of allowed emission in the cascade. */ inline int maxEmissions() const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** * Exception class used if the outgoing multiplicity is out of range * or the maximum multiplicity is larger than the minimum in * reweightCKKW. */ struct CKKWMultiplicityException: Exception {}; /** * Exception class used if the dipole state is not self consistant at * any stage of the cascade. */ struct IntegretyException: Exception {}; protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ inline virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ inline virtual IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Check sanity of the object during the setup phase. */ - inline virtual void doupdate() throw(UpdateException); + inline virtual void doupdate(); /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ - virtual void doinit() throw(InitException); + virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ inline virtual void doinitrun(); /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ inline virtual void dofinish(); /** * Rebind pointers to other Interfaced objects. Called in the setup phase * after all objects used in an EventGenerator has been cloned so that * the pointers will refer to the cloned objects afterwards. * @param trans a TranslationMap relating the original objects to * their respective clones. * @throws RebindException if no cloned object was found for a given * pointer. */ - inline virtual void rebind(const TranslationMap & trans) - throw(RebindException); + inline virtual void rebind(const TranslationMap & trans); /** * Return a vector of all pointers to Interfaced objects used in this * object. * @return a vector of pointers. */ inline virtual IVector getReferences(); /** * Return true if this object needs to be initialized before all * other objects because it needs to extract PDFs from the event * file. This version will return true if runningCoupling() returns * internalRunning and no internalAlphaS() object has been given. */ virtual bool preInitialize() const; //@} private: /** * Function used by the interface. */ Energy minPTCut() const; /** * Function used by the interface. */ Energy maxLambdaQCD() const; private: /** * Strategy for \f$\alpha_S\f$. 0 means constant a constant * \f$\alpha_S\f$ with a value given by alpha0(). 1 means a leading * order running \f$\alpha_S\f$ with a \f$\Lambda_{QCD}\f$ given by * lambdaQCD(). -1 means take whatever is specified in the current * StandardModelBase object. */ RunningOption theRunningCoupling; /** * The constant \f$\alpha_S\f$ to be used if runningCoupling() is * noRunning. */ double theAlpha0; /** * The \f$\Lambda_{QCD}\f$ to use in the one loop running * \f$\alpha_S\f$ if runningCoupling is simpleRunning. */ Energy theLambdaQCD; /** * An internal \f$\alpha_S\f$ object to be used if runningCoupling() * is internalRunning. */ Ptr::pointer theInternalAlphaS; /** * The cutoff in invariant transverse momentum for QCD emissions. */ Energy thePTCut; /** * The constant \f$\alpha_{EM}\f$ to be used. If zero, use whatever * is specified in the current StandardModelBase object. */ double theAlphaEM0; /** * The cutoff in invariant transverse momentum for QED emissions. */ Energy thePTCutEM; /** * The number of different colour indices available to dipoles. */ int theNCol; /** * The number of possible flavours in a \f$g\to q\bar{q}\f$ splitting. */ int theNFlav; /** * Switch to turn on and off photon emission in the cascade. */ bool thePhotonEmissions; /** * The inverse extension of a hadron remnant. */ Energy theSoftMu; /** * The dimension assumed for the extension of a hadron remnant. */ double theSoftAlpha; /** * The dimension assumed for the extension of a hard remnant. */ double theHardAlpha; /** * The power in the suppression of radiation from extended dipoles. */ double theBeta; /** * A list of reweighting objects which may be applied to dipole * emissions. */ vector theReweighters; /** * A list of leading-order matrix-element correction objects which * may be applied to dipole emissions. */ MECVector theMECorrectors; /** * The maximum number of emissions allowed in the cascade. */ int theMaxEmissions; /** * A map containing the states generated by reweight CKKW. The map * assiciates an XComb to a struct containing the dipole state, the * rotation, the last pt2 and a boolean which specifies if the state * has the maximum parton multiplicity or not. */ struct CKKWState { DipoleStatePtr state; LorentzRotation rotation; Energy2 pt2; bool maxMult; }; map theCKKWMap; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initCascadeHandler; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ CascadeHandler & operator=(const CascadeHandler &); }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of CascadeHandler. */ template <> struct BaseClassTrait { /** Typedef of the first base class of CascadeHandler. */ typedef CascadeHandler NthBase; }; /** This template specialization informs ThePEG about the name of * the CascadeHandler class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "Ariadne::CascadeHandler"; } /** Return the name of the shared library be loaded to get * access to the CascadeHandler class and every other class it uses * (except the base class). */ static string library() { return "libArCascade.so"; } }; /** @endcond */ } #include "CascadeHandler.icc" #ifndef ThePEG_TEMPLATES_IN_CC_FILE // #include "CascadeHandler.tcc" #endif #endif /* ARIADNE_CascadeHandler_H */ diff --git a/DipoleCascade/CascadeHandler.icc b/DipoleCascade/CascadeHandler.icc --- a/DipoleCascade/CascadeHandler.icc +++ b/DipoleCascade/CascadeHandler.icc @@ -1,119 +1,118 @@ // -*- C++ -*- // // This is the implementation of the inlined member functions of // the CascadeHandler class. // namespace Ariadne { inline IBPtr CascadeHandler::clone() const { return new_ptr(*this); } inline IBPtr CascadeHandler::fullclone() const { return new_ptr(*this); } inline CascadeHandler::RunningOption CascadeHandler::runningCoupling() const { return theRunningCoupling; } inline double CascadeHandler::alpha0() const { return theAlpha0; } inline double CascadeHandler::alphaEM0() const { return theAlphaEM0; } inline Energy CascadeHandler::lambdaQCD() const { return theLambdaQCD; } inline Ptr::const_pointer CascadeHandler::internalAlphaS() const { return theInternalAlphaS; } inline Energy CascadeHandler::pTCut() const { return thePTCut; } inline Energy CascadeHandler::pTCutEM() const { return thePTCutEM; } inline int CascadeHandler::nCol() const { return theNCol; } inline int CascadeHandler::nFlav() const { return theNFlav; } inline bool CascadeHandler::photonEmissions() const { return thePhotonEmissions; } inline int CascadeHandler::maxEmissions() const { return theMaxEmissions; } inline Energy CascadeHandler::softMu() const { return theSoftMu; } inline double CascadeHandler::softAlpha() const { return theSoftAlpha; } inline double CascadeHandler::hardAlpha() const { return theHardAlpha >= 0? theHardAlpha: softAlpha(); } inline double CascadeHandler::beta() const { return theBeta; } inline const CascadeHandler::MECVector & CascadeHandler::MECorrectors() const { return theMECorrectors; } -inline void CascadeHandler::doupdate() throw(UpdateException) { +inline void CascadeHandler::doupdate() { ThePEG::CascadeHandler::doupdate(); // First update base class. bool redo = touched(); // redo if touched. // UpdateChecker::check(aDependentMember, redo); // Update referenced objects on which this depends redo is set to true // if the dependent object is touched. // for_each(ContainerOfDependencies, UpdateChecker(redo)); // Update a container of references. // for_each(MapOfDependencies, UpdateMapChecker(redo)); // Update a map of references. if ( !redo ) return; // return if nothing has been touched. Otherwise do the actual update. // touch() // Touch if anything has changed. } inline void CascadeHandler::dofinish() { ThePEG::CascadeHandler::dofinish(); } inline void CascadeHandler::doinitrun() { ThePEG::CascadeHandler::doinitrun(); } -inline void CascadeHandler::rebind(const TranslationMap & trans) - throw(RebindException) { +inline void CascadeHandler::rebind(const TranslationMap & trans) { // dummy = trans.translate(dummy); ThePEG::CascadeHandler::rebind(trans); } inline IVector CascadeHandler::getReferences() { IVector ret = ThePEG::CascadeHandler::getReferences(); // ret.push_back(dummy); return ret; } } diff --git a/src/DISAnalysis.cc b/src/DISAnalysis.cc --- a/src/DISAnalysis.cc +++ b/src/DISAnalysis.cc @@ -1,159 +1,159 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the DISAnalysis class. // #include "DISAnalysis.h" #include "ThePEG/Interface/ClassDocumentation.h" #ifdef ThePEG_TEMPLATES_IN_CC_FILE // #include "DISAnalysis.tcc" #endif #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/EventRecord/Event.h" #include "ThePEG/EventRecord/RemnantParticle.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/PDT/StandardMatchers.h" #include "ThePEG/PDT/RemnantDecayer.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Handlers/EventHandler.h" #include "ThePEG/Handlers/LastXCombInfo.h" #include "ThePEG/Handlers/XComb.h" #include "ThePEG/Utilities/UtilityBase.h" #ifndef LWH_AIAnalysisFactory_H #ifndef LWH #define LWH ThePEGLWH #endif #include "ThePEG/Analysis/LWH/AnalysisFactory.h" #endif using namespace Ariadne; using namespace ThePEG; DISAnalysis::~DISAnalysis() {} -void DISAnalysis::doinit() throw(InitException) { +void DISAnalysis::doinit() { AnalysisHandler::doinit(); checkHistogramFactory(true); } void DISAnalysis::doinitrun() { AnalysisHandler::doinitrun(); if ( !checkHistogramFactory(true) ) return; histogramFactory().registerClient(this); histogramFactory().mkdirs("/DISAnalysis"); histogramFactory().cd("/DISAnalysis"); histY = histogramFactory().createHistogram1D ("y", "y", 100, 0.0, 1.0); histQ2 = histogramFactory().createHistogram1D ("Q2", "Q2", 100, 0.0, 100.0); histW = histogramFactory().createHistogram1D ("W", "W", 100, 0.0, 100.0); histX = histogramFactory().createHistogram1D ("logx", "Log10(Bjorken-x)", 100, -4.0, 0.0); histYQ = histogramFactory().createHistogram1D ("yq", "Quark rapidity", 100, -6.0, 4.0); histPTQ = histogramFactory().createHistogram1D ("pty", "Quark pT", 40, 0.0, 20.0); histYG = histogramFactory().createHistogram1D ("yg", "Gluon rapidity", 100, -6.0, 4.0); histPTG = histogramFactory().createHistogram1D ("ptg", "Gluon pT", 40, 0.0, 20.0); } void DISAnalysis::dofinish() { AnalysisHandler::dofinish(); if ( !checkHistogramFactory() ) return; normalize(histY); normalize(histQ2); normalize(histW); normalize(histX); normalize(histYQ); normalize(histPTQ); normalize(histYG); normalize(histPTG); } void DISAnalysis::analyze(tEventPtr event, long ieve, int loop, int state) { const PPair & incoming = event->primaryCollision()->incoming(); tcPPtr proton = incoming.first; tcPPtr iniLep = incoming.second; if(incoming.second->id() == ParticleID::pplus){ proton = incoming.second; iniLep = incoming.first; } const SubProcess & sub = *event->primarySubProcess(); tcPPtr q = sub.outgoing()[0]; tcPPtr finLep = sub.outgoing()[1]; if( ! QuarkMatcher::Check(q->data()) ){ q = sub.outgoing()[1]; finLep = sub.outgoing()[0]; } LorentzMomentum pIniLep = iniLep->momentum(); LorentzMomentum pFinLep = finLep->momentum(); pp = proton->momentum(); pq = pIniLep - pFinLep; Energy2 Q2 = -pq.m2(); Energy W = (pq + pp).m(); histQ2->fill( Q2/GeV2 ); histX->fill(log10( Q2 / (2 * pp.dot(pq)) )); histY->fill( pp.dot(pq) / pp.dot(pIniLep) ); histW->fill( W / GeV ); AnalysisHandler::analyze(event, ieve, loop, state); } LorentzRotation DISAnalysis::transform(tEventPtr event) const { return Utilities::getBoostToCM( make_pair( pp, pq ) ); } void DISAnalysis::analyze(const tPVector & particles) { AnalysisHandler::analyze(particles); } void DISAnalysis::analyze(tPPtr p) { if(QuarkMatcher::Check(p->data())){ tParticleVector parents = p->parents(); bool rem = false; for ( int j = 0, M = parents.size(); j < M; ++j ) { if(dynamic_ptr_cast(parents[j])){ rem = true; } } if(!rem){ histYQ->fill( p->rapidity() ); histPTQ->fill( p->mt() / GeV ); } } else if(p->id() == ParticleID::g){ histYG->fill( p->rapidity() ); histPTG->fill( p->mt() / GeV ); } } void DISAnalysis::persistentOutput(PersistentOStream & os) const { // *** ATTENTION *** os << ; // Add all member variable which should be written persistently here. } void DISAnalysis::persistentInput(PersistentIStream & is, int) { // *** ATTENTION *** is >> ; // Add all member variable which should be read persistently here. } ClassDescription DISAnalysis::initDISAnalysis; // Definition of the static class description member. void DISAnalysis::Init() { static ClassDocumentation documentation ("There is no documentation for the DISAnalysis class"); } diff --git a/src/DISAnalysis.h b/src/DISAnalysis.h --- a/src/DISAnalysis.h +++ b/src/DISAnalysis.h @@ -1,222 +1,222 @@ // -*- C++ -*- #ifndef THEPEG_DISAnalysis_H #define THEPEG_DISAnalysis_H // // This is the declaration of the DISAnalysis class. // #include "ThePEG/Handlers/AnalysisHandler.h" #include "ThePEG/Vectors/LorentzVector.h" namespace Ariadne { using namespace ThePEG; /** * Plots several histograms related to DIS. * * @see \ref DISAnalysisInterfaces "The interfaces" * defined for DISAnalysis. */ class DISAnalysis: public AnalysisHandler { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ inline DISAnalysis(); /** * The copy constructor. */ inline DISAnalysis(const DISAnalysis &); /** * The destructor. */ virtual ~DISAnalysis(); //@} public: /** @name Virtual functions required by the AnalysisHandler class. */ //@{ /** * Analyze a given Event. Note that a fully generated event * may be presented several times, if it has been manipulated in * between. The default version of this function will call transform * to make a lorentz transformation of the whole event, then extract * all final state particles and call analyze(tPVector) of this * analysis object and those of all associated analysis objects. The * default version will not, however, do anything on events which * have not been fully generated, or have been manipulated in any * way. * @param event pointer to the Event to be analyzed. * @param ieve the event number. * @param loop the number of times this event has been presented. * If negative the event is now fully generated. * @param state a number different from zero if the event has been * manipulated in some way since it was last presented. */ virtual void analyze(tEventPtr event, long ieve, int loop, int state); /** * Transform the event to the desired Lorentz frame and return the * corresponding LorentzRotation. * @param event a pointer to the Event to be transformed. * @return the LorentzRotation used in the transformation. */ virtual LorentzRotation transform(tEventPtr event) const; /** * Analyze the given vector of particles. The default version calls * analyze(tPPtr) for each of the particles. * @param particles the vector of pointers to particles to be analyzed */ virtual void analyze(const tPVector & particles); /** * Analyze the given particle. * @param particle pointer to the particle to be analyzed. */ virtual void analyze(tPPtr particle); //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ inline virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ inline virtual IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving and * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ - virtual void doinit() throw(InitException); + virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ virtual void dofinish(); //@} private: tH1DPtr histY, histQ2, histX, histYQ, histPTQ, histYG, histPTG, histW; /** * Proton and boson momentum. */ LorentzMomentum pp, pq; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initDISAnalysis; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ DISAnalysis & operator=(const DISAnalysis &); }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of DISAnalysis. */ template <> struct BaseClassTrait { /** Typedef of the first base class of DISAnalysis. */ typedef AnalysisHandler NthBase; }; /** This template specialization informs ThePEG about the name of * the DISAnalysis class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "Ariadne::DISAnalysis"; } /** * The name of a file containing the dynamic library where the class * DISAnalysis is implemented. It may also include several, space-separated, * libraries if the class DISAnalysis depends on other classes (base classes * excepted). In this case the listed libraries will be dynamically * linked in the order they are specified. */ static string library() { return "DISAnalysis.so"; } }; /** @endcond */ } #include "DISAnalysis.icc" #ifndef ThePEG_TEMPLATES_IN_CC_FILE // #include "DISAnalysis.tcc" #endif #endif /* THEPEG_DISAnalysis_H */ diff --git a/src/DYAnalysis.cc b/src/DYAnalysis.cc --- a/src/DYAnalysis.cc +++ b/src/DYAnalysis.cc @@ -1,154 +1,154 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the DYAnalysis class. // #include "DYAnalysis.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Event.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/PDT/StandardMatchers.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Repository/EventGenerator.h" #ifdef ThePEG_TEMPLATES_IN_CC_FILE // #include "DYAnalysis.tcc" #endif #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #ifndef LWH_AIAnalysisFactory_H #ifndef LWH #define LWH ThePEGLWH #endif #include "ThePEG/Analysis/LWH/AnalysisFactory.h" #endif using namespace ThePEG; using namespace Ariadne; DYAnalysis::~DYAnalysis() {} -void DYAnalysis::doinit() throw(InitException) { +void DYAnalysis::doinit(){ AnalysisHandler::doinit(); checkHistogramFactory(true); } void DYAnalysis::doinitrun() { AnalysisHandler::doinitrun(); if ( !checkHistogramFactory(true) ) return; histogramFactory().registerClient(this); histogramFactory().mkdirs("/DYAnalysis"); histogramFactory().cd("/DYAnalysis"); histPt = histogramFactory().createHistogram1D ("Pt", "Transverse momentum of Drell-Yan pair", 100, 0.0, 400.0); histEta = histogramFactory().createHistogram1D ("Eta", "Pseudo-rapidity of Drell-Yan pair", 40, -5.0, 5.0); histY = histogramFactory().createHistogram1D ("Y", "Rapidity of Drell-Yan pair", 40, -5.0, 5.0); histMass = histogramFactory().createHistogram1D ("Mass", "Invariant mass of Drell-Yan pair", 100, 0.0, 500.0); histCPt = histogramFactory().createHistogram1D ("CPt", "Transverse momentum of Drell-Yan pair in |y|<1", 100, 0.0, 400.0); histYG = histogramFactory().createHistogram1D ("YG", "Rapidity of the emitted gluon", 40, -5.0, 5.0); histYQ = histogramFactory().createHistogram1D ("YQ", "Rapidity of the emitted quark", 40, -5.0, 5.0); histNG = histogramFactory().createHistogram1D ("NG", "Number of gluons", 50, 0.0, 50.0); histPTG = histogramFactory().createHistogram1D ("PTG", "Transverse momentum of gluons", 100, 0.0, 100.0); histPTQ = histogramFactory().createHistogram1D ("PTQ", "Transverse momentum of quarks", 100, 0.0, 100.0); } void DYAnalysis::dofinish() { AnalysisHandler::dofinish(); if ( !checkHistogramFactory() ) return; normalize(histPt); normalize(histEta); normalize(histY); normalize(histYG); normalize(histYQ); normalize(histMass); normalize(histCPt); normalize(histNG); normalize(histPTG); normalize(histPTQ); } void DYAnalysis::analyze(tEventPtr event, long ieve, int loop, int state) { AnalysisHandler::analyze(event, ieve, loop, state); } LorentzRotation DYAnalysis::transform(tEventPtr event) const { return LorentzRotation(); // Return the Rotation to the frame in which you want to perform the analysis. } void DYAnalysis::analyze(const tPVector & particles) { AnalysisHandler::analyze(particles); if ( !checkHistogramFactory() ) return; tPPair dypair; Energy2 mins = Constants::MaxEnergy2; int ng = 0; for ( int i = 0, N = particles.size(); i < N; ++i ) { if ( particles[i]->id() == ParticleID::g ){ histYG->fill(particles[i]->momentum().rapidity()); ng++; if(abs(particles[i]->momentum().eta()) < 2.5){ histPTG->fill(particles[i]->momentum().perp()/GeV); } } if ( QuarkMatcher::Check(particles[i]->data()) ) { LorentzMomentum pq = particles[i]->momentum(); histPTQ->fill(pq.perp()/GeV); if(pq.perp() > 20*GeV){ histYQ->fill(pq.rapidity()); } } if ( !LeptonMatcher::Check(particles[i]->data()) ) continue; if ( !ChargedMatcher::Check(particles[i]->data()) ) continue; for ( int j = i + 1, M = particles.size(); j < M; ++j ) { if ( particles[i]->id() + particles[j]->id() != 0 ) continue; Energy2 s = ( particles[i]->momentum() + particles[j]->momentum() ).m2(); if ( s >= mins ) continue; dypair = make_pair(particles[i], particles[j]); mins = s; } } histNG->fill(ng); if ( !dypair.first ) return; LorentzMomentum pdy = dypair.first->momentum() + dypair.second->momentum(); double y = pdy.rapidity(); Energy pt = pdy.perp(); histPt->fill(pt/GeV); histEta->fill(pdy.eta()); histY->fill(y); histMass->fill(sqrt(mins)/GeV); if ( abs(y) < 1.0 ) histCPt->fill(pt/GeV); } void DYAnalysis::analyze(tPPtr) {} void DYAnalysis::persistentOutput(PersistentOStream & os) const {} void DYAnalysis::persistentInput(PersistentIStream & is, int) {} ClassDescription DYAnalysis::initDYAnalysis; // Definition of the static class description member. void DYAnalysis::Init() { static ClassDocumentation documentation ("The DYAnalysis class collects a number of histograms related to " "Drell-Yan production."); } diff --git a/src/DYAnalysis.h b/src/DYAnalysis.h --- a/src/DYAnalysis.h +++ b/src/DYAnalysis.h @@ -1,214 +1,214 @@ // -*- C++ -*- #ifndef THEPEG_DYAnalysis_H #define THEPEG_DYAnalysis_H // // This is the declaration of the DYAnalysis class. // #include "ThePEG/Handlers/AnalysisHandler.h" namespace Ariadne { using namespace ThePEG; /** * The DYAnalysis class collects a number of histograms related to * Drell-Yan production. * */ class DYAnalysis: public AnalysisHandler { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ inline DYAnalysis(); /** * The copy constructor. */ inline DYAnalysis(const DYAnalysis &); /** * The destructor. */ virtual ~DYAnalysis(); //@} public: /** @name Virtual functions required by the AnalysisHandler class. */ //@{ /** * Analyze a given Event. Note that a fully generated event * may be presented several times, if it has been manipulated in * between. The default version of this function will call transform * to make a lorentz transformation of the whole event, then extract * all final state particles and call analyze(tPVector) of this * analysis object and those of all associated analysis objects. The * default version will not, however, do anything on events which * have not been fully generated, or have been manipulated in any * way. * @param event pointer to the Event to be analyzed. * @param ieve the event number. * @param loop the number of times this event has been presented. * If negative the event is now fully generated. * @param state a number different from zero if the event has been * manipulated in some way since it was last presented. */ virtual void analyze(tEventPtr event, long ieve, int loop, int state); /** * Transform the event to the desired Lorentz frame and return the * corresponding LorentzRotation. * @param event a pointer to the Event to be transformed. * @return the LorentzRotation used in the transformation. */ virtual LorentzRotation transform(tEventPtr event) const; /** * Analyze the given vector of particles. The default version calls * analyze(tPPtr) for each of the particles. * @param particles the vector of pointers to particles to be analyzed */ virtual void analyze(const tPVector & particles); /** * Analyze the given particle. * @param particle pointer to the particle to be analyzed. */ virtual void analyze(tPPtr particle); //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ inline virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ inline virtual IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving and * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ - virtual void doinit() throw(InitException); + virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ virtual void dofinish(); //@} private: tH1DPtr histPt, histEta, histY, histYQ, histYG, histMass, histCPt; tH1DPtr histNG, histPTG, histPTQ; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initDYAnalysis; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ DYAnalysis & operator=(const DYAnalysis &); }; } // CLASSDOC OFF #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of DYAnalysis. */ template <> struct BaseClassTrait { /** Typedef of the first base class of DYAnalysis. */ typedef AnalysisHandler NthBase; }; /** This template specialization informs ThePEG about the name of * the DYAnalysis class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "Ariadne::DYAnalysis"; } /** Return the name of the shared library be loaded to get * access to the DYAnalysis class and every other class it uses * (except the base class). */ static string library() { return "DYAnalysis.so"; } }; /** @endcond */ } #include "DYAnalysis.icc" #ifndef ThePEG_TEMPLATES_IN_CC_FILE // #include "DYAnalysis.tcc" #endif #endif /* THEPEG_DYAnalysis_H */ diff --git a/src/FTuneLEP/FTuneLEP.in b/src/FTuneLEP/FTuneLEP.in --- a/src/FTuneLEP/FTuneLEP.in +++ b/src/FTuneLEP/FTuneLEP.in @@ -1,231 +1,281 @@ mkdir /Ariadne5/MultiLEP cd /Ariadne5/MultiLEP create ThePEG::MultiEventGenerator MultiLEPGenerator MultiEventGenerator.so # set MultiLEPGenerator:Path FTune set MultiLEPGenerator:EventHandler /Ariadne5/Generators/LEP/LEPGenerator:EventHandler set MultiLEPGenerator:RandomNumberGenerator /Ariadne5/Generators/LEP/LEPGenerator:RandomNumberGenerator cp /Defaults/Random RandomArg set MultiLEPGenerator:SeparateRandom RandomArg set MultiLEPGenerator:StandardModelParameters /Ariadne5/Generators/LEP/LEPGenerator:StandardModelParameters set MultiLEPGenerator:Strategy /Ariadne5/StdStrategy set MultiLEPGenerator:NumberOfEvents 100000 set MultiLEPGenerator:DebugLevel 0 set MultiLEPGenerator:PrintEvent 0 create ThePEG::RivetAnalysis RivetLEP RivetAnalysis.so insert RivetLEP:Paths[0] . insert RivetLEP:Analyses[0] SLD_2004_S5693039 insert RivetLEP:Analyses[0] PDG_HADRON_MULTIPLICITIES_RATIOS insert RivetLEP:Analyses[0] PDG_HADRON_MULTIPLICITIES insert RivetLEP:Analyses[0] DELPHI_1996_S3430090 insert RivetLEP:Analyses[0] DELPHI_2002_069_CONF_603 insert RivetLEP:Analyses[0] DELPHI_2000_S4328825 insert RivetLEP:Analyses[0] OPAL_1998_S3780481 +insert RivetLEP:Analyses[0] JADE_OPAL_2000_S4300807 +insert RivetLEP:Analyses[0] ALEPH_2004_S5765862 insert RivetLEP:Analyses[0] MC_LHQG_EE insert MultiLEPGenerator:AnalysisHandlers[0] RivetLEP do MultiLEPGenerator:AddRndInterface /Ariadne5/Defaults/Frag8:StringZ_aLund 200 0.05 2.0 0.3 0.2 do MultiLEPGenerator:AddRndInterface /Ariadne5/Defaults/Frag8:StringZ_bLund 1 0.21 2.0 0.80 0.4 do MultiLEPGenerator:AddRndInterface /Ariadne5/Defaults/Frag8:StringPT_sigma 1 0.05 1.0 0.3 0.2 do MultiLEPGenerator:AddRndInterface /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 1 0.0 1.0 0.09 0.05 do MultiLEPGenerator:AddRndInterface /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 1 0.0 1.0 0.19 0.10 set /Ariadne5/Cascade/BasicConsistency:CheckGluonPT Off erase /Ariadne5/Cascade/Models/FSGluon:Reweighters[0] cp /Ariadne5/Cascade/AriadneCascade AriadneSwingCascade set AriadneSwingCascade:PurgeStrategy BeforeAndAfter set AriadneSwingCascade:PurgeFactor 1.0 create Ariadne5::DipoleSwinger Swinger do Swinger:SetRmax -2.7 set Swinger:SizeOpt 1 set Swinger:Lambda 1 set Swinger:Linear Logarithmic set Swinger:RhoCut -1.0 insert AriadneSwingCascade:Emitters[0] Swinger cp /Ariadne5/Generators/LEP/LEPHandler SwingHandler set SwingHandler:CascadeHandler AriadneSwingCascade create ThePEG::ProgressLog Logger ProgressLog.so set Logger:Interval 600 insert MultiLEPGenerator:AnalysisHandlers[0] Logger cp MultiLEPGenerator MultiLEPGeneratorSw set MultiLEPGeneratorSw:EventHandler SwingHandler saverun FTuneLEP01 MultiLEPGenerator saverun FTuneLEP02 MultiLEPGenerator set MultiLEPGeneratorSw:NumberOfEvents 10000 saverun FTuneSwLEP11 MultiLEPGeneratorSw saverun FTuneSwLEP02 MultiLEPGeneratorSw saverun FTuneSwLEP12 MultiLEPGeneratorSw set MultiLEPGeneratorSw:NumberOfEvents 100000 saverun FTuneSwLEP03 MultiLEPGeneratorSw saverun FTuneSwLEP13 MultiLEPGeneratorSw insert /Ariadne5/Cascade/Models/FSGluon:Reweighters[0] /Ariadne5/Cascade/Models/ColourChargeRegions saverun FTuneSwLEP19 MultiLEPGeneratorSw erase /Ariadne5/Cascade/Models/FSGluon:Reweighters[0] saverun FTuneSwLEP20 MultiLEPGeneratorSw set AriadneSwingCascade:LambdaQCD 0.25 saverun FTuneSwLEP14 MultiLEPGeneratorSw set AriadneSwingCascade:LambdaQCD 0.11 saverun FTuneSwLEP16 MultiLEPGeneratorSw set AriadneSwingCascade:LambdaQCD 0.38 saverun FTuneSwLEP17 MultiLEPGeneratorSw set AriadneSwingCascade:LambdaQCD 0.05 saverun FTuneSwLEP18 MultiLEPGeneratorSw set AriadneSwingCascade:LambdaQCD 0.22 cp MultiLEPGeneratorSw MultiLEPGeneratorSw2 do MultiLEPGeneratorSw2:RemoveInterface /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ do MultiLEPGeneratorSw2:RemoveInterface /Ariadne5/Defaults/Frag8:StringFlav_probStoUD do MultiLEPGeneratorSw2:AddRndInterface AriadneSwingCascade:LambdaQCD 1 0.1 0.3 0.2 0.6 do MultiLEPGeneratorSw2:AddRndInterface AriadneSwingCascade:PTCut 1 0.4 0.8 0.6 0.12 set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.08 set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.22 saverun FTuneSwLEP15 MultiLEPGeneratorSw2 insert /Ariadne5/Cascade/Models/FSGluon:Reweighters[0] /Ariadne5/Cascade/Models/ColourChargeRegions saverun FTuneSwLEP21 MultiLEPGeneratorSw2 erase /Ariadne5/Cascade/Models/FSGluon:Reweighters[0] get /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ get /Ariadne5/Defaults/Frag8:StringFlav_probStoUD saverun FTuneSwLEP22 MultiLEPGeneratorSw2 set Swinger:MaxRho 1.0 saverun FTuneswLEP03 MultiLEPGeneratorSw set Swinger:MaxRho -2.0 set /Ariadne5/Defaults/Frag8:FragmentationScheme dipole set /Ariadne5/Defaults/Frag8:StringR0 1.2 set /Ariadne5/Defaults/Frag8:Stringm0 0.6 set /Ariadne5/Defaults/Frag8:ThrowAway true saverun FTuneSwLEP04 MultiLEPGeneratorSw set /Ariadne5/Defaults/Frag8:FragmentationScheme dipole set /Ariadne5/Defaults/Frag8:StringR0 1.0 set /Ariadne5/Defaults/Frag8:Stringm0 0.2 set /Ariadne5/Defaults/Frag8:BaryonSuppression 0.2 set /Ariadne5/Defaults/Frag8:Average false set /Ariadne5/Defaults/Frag8:ThrowAway true saverun FTuneSwLEP05 MultiLEPGeneratorSw set MultiLEPGeneratorSw:NumberOfEvents 10000 saverun FTuneSwLEP06 MultiLEPGeneratorSw set MultiLEPGeneratorSw:NumberOfEvents 100000 set /Ariadne5/Defaults/Frag8:BaryonSuppression 0.25 saverun FTuneSwLEP07 MultiLEPGeneratorSw set MultiLEPGeneratorSw:NumberOfEvents 10000 saverun FTuneSwLEP08 MultiLEPGeneratorSw set /Ariadne5/Defaults/Frag8:BaryonSuppression 0.2 set MultiLEPGeneratorSw:NumberOfEvents 100000 set /Ariadne5/Defaults/Frag8:FragmentationScheme none set /Ariadne5/Defaults/Frag8:StringR0 0.5 set /Ariadne5/Defaults/Frag8:Stringm0 1.0 set /Ariadne5/Defaults/Frag8:ThrowAway false do MultiLEPGenerator:RemoveInterface /Ariadne5/Defaults/Frag8:StringZ_aLund do MultiLEPGenerator:RemoveInterface /Ariadne5/Defaults/Frag8:StringZ_bLund do MultiLEPGenerator:RemoveInterface /Ariadne5/Defaults/Frag8:StringPT_sigma do MultiLEPGenerator:RemoveInterface /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ do MultiLEPGenerator:RemoveInterface /Ariadne5/Defaults/Frag8:StringFlav_probStoUD set MultiLEPGenerator:NumberOfEvents 1000000 set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.23 set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.34 set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.33 set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.09 set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.19 saverun FTuneLEP01w MultiLEPGenerator set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.309 set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.311 set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.033 set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.0001 set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.0001 saverun FTuneLEP01W MultiLEPGenerator set MultiLEPGenerator:NumberOfEvents 10000000 set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.32 set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.39 set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.32 set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.078 set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.22 saverun FTuneLEP02t MultiLEPGenerator +saverun Swaptest MultiLEPGenerator + set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.30 set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.36 set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.33 set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.082 set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.22 saverun FTuneLEP01t MultiLEPGenerator set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.72 set MultiLEPGenerator:NumberOfEvents 1000000 saverun FTuneLEP01b2 MultiLEPGenerator set /Ariadne5/Defaults/Frag8:StringZ_bLund 1.08 saverun FTuneLEP01b4 MultiLEPGenerator set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.36 set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.15 saverun FTuneLEP01a2 MultiLEPGenerator set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.03 saverun FTuneLEP01a4 MultiLEPGenerator set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.001 saverun FTuneLEP01a5 MultiLEPGenerator set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.30 set MultiLEPGenerator:NumberOfEvents 10000000 do MultiLEPGeneratorSw:RemoveInterface /Ariadne5/Defaults/Frag8:StringZ_aLund do MultiLEPGeneratorSw:RemoveInterface /Ariadne5/Defaults/Frag8:StringZ_bLund do MultiLEPGeneratorSw:RemoveInterface /Ariadne5/Defaults/Frag8:StringPT_sigma do MultiLEPGeneratorSw:RemoveInterface /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ do MultiLEPGeneratorSw:RemoveInterface /Ariadne5/Defaults/Frag8:StringFlav_probStoUD set MultiLEPGeneratorSw:NumberOfEvents 10000000 set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.43 set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.42 set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.31 set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.080 set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.21 saverun FTuneSwLEP13t MultiLEPGeneratorSw +insert /Ariadne5/Cascade/Models/FSGluon:Reweighters[0] /Ariadne5/Cascade/Models/ColourChargeRegions +set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.427 +set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.376 +set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.321 +set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.0771 +set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.217 +saverun FTuneSwLEP19t MultiLEPGeneratorSw +erase /Ariadne5/Cascade/Models/FSGluon:Reweighters[0] + +set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.477 +set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.446 +set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.315 +set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.0792 +set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.216 +saverun FTuneSwLEP20t MultiLEPGeneratorSw + +set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.08 +set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.22 +set AriadneSwingCascade:LambdaQCD 2.799416e-01 +set AriadneSwingCascade:PTCut 7.221026e-01 +set /Ariadne5/Defaults/Frag8:StringPT_sigma 2.957804e-01 +set /Ariadne5/Defaults/Frag8:StringZ_aLund 5.006885e-01 +set /Ariadne5/Defaults/Frag8:StringZ_bLund 5.154711e-01 +insert /Ariadne5/Cascade/Models/FSGluon:Reweighters[0] /Ariadne5/Cascade/Models/ColourChargeRegions +saverun FTuneSwLEP21t MultiLEPGeneratorSw +erase /Ariadne5/Cascade/Models/FSGluon:Reweighters[0] + +set AriadneSwingCascade:LambdaQCD 2.813344e-01 +set AriadneSwingCascade:PTCut 4.970300e-01 +set /Ariadne5/Defaults/Frag8:StringPT_sigma 2.961634e-01 +set /Ariadne5/Defaults/Frag8:StringZ_aLund 4.156573e-01 +set /Ariadne5/Defaults/Frag8:StringZ_bLund 5.647802e-01 +saverun FTuneSwLEP15t MultiLEPGeneratorSw + +set AriadneSwingCascade:LambdaQCD 2.515900e-01 +set AriadneSwingCascade:PTCut 5.259991e-01 +set /Ariadne5/Defaults/Frag8:StringPT_sigma 2.943233e-01 +set /Ariadne5/Defaults/Frag8:StringZ_aLund 4.906624e-01 +set /Ariadne5/Defaults/Frag8:StringZ_bLund 5.407769e-01 +saverun FTuneSwLEP22t MultiLEPGeneratorSw + +setdef AriadneSwingCascade:LambdaQCD +setdef AriadneSwingCascade:PTCut + + + set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.42 set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.40 set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.32 set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.084 set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.22 saverun FTuneSwLEP01t MultiLEPGeneratorSw saverun FTuneSwLEP02t MultiLEPGeneratorSw saverun FTuneSwLEP02t73 MultiLEPGeneratorSw saverun FTuneSwLEP03t MultiLEPGeneratorSw set MultiLEPGeneratorSw:LogNonDefault 1 saverun FTuneSwLEP04t MultiLEPGeneratorSw saverun FTuneSwLEP04n MultiLEPGeneratorSw set /Ariadne5/Defaults/Frag8:FragmentationScheme dipole set /Ariadne5/Defaults/Frag8:StringR0 1.2 set /Ariadne5/Defaults/Frag8:Stringm0 0.6 set /Ariadne5/Defaults/Frag8:ThrowAway true set MultiLEPGeneratorSw:NumberOfEvents 1000000 saverun FTuneSwLEP03d MultiLEPGeneratorSw set /Ariadne5/Defaults/Frag8:FragmentationScheme dipole set /Ariadne5/Defaults/Frag8:StringR0 1.0 set /Ariadne5/Defaults/Frag8:Stringm0 0.2 set /Ariadne5/Defaults/Frag8:BaryonSuppression 0.2 set /Ariadne5/Defaults/Frag8:Average false set /Ariadne5/Defaults/Frag8:ThrowAway true saverun FTuneSwLEP03e MultiLEPGeneratorSw set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.48 set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.41 set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.31 set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.075 set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.21 saverun FTuneSwLEP05t MultiLEPGeneratorSw set /Ariadne5/Defaults/Frag8:BaryonSuppression 0.25 set /Ariadne5/Defaults/Frag8:StringZ_aLund 0.41 set /Ariadne5/Defaults/Frag8:StringZ_bLund 0.37 set /Ariadne5/Defaults/Frag8:StringPT_sigma 0.31 set /Ariadne5/Defaults/Frag8:StringFlav_probQQtoQ 0.073 set /Ariadne5/Defaults/Frag8:StringFlav_probStoUD 0.21 saverun FTuneSwLEP07t MultiLEPGeneratorSw diff --git a/src/MEqq2gZ2ll.cc b/src/MEqq2gZ2ll.cc --- a/src/MEqq2gZ2ll.cc +++ b/src/MEqq2gZ2ll.cc @@ -1,170 +1,170 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the MEqq2gZ2ll class. // #include "MEqq2gZ2ll.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; using namespace Herwig; MEqq2gZ2ll::MEqq2gZ2ll() : coefs(20), mZ2(0.0*GeV2), GZ2(0.0*GeV2), lastCont(0.0), lastBW(0.0) {} MEqq2gZ2ll::MEqq2gZ2ll(const MEqq2gZ2ll & x) : ME2to2QCD(x), coefs(x.coefs), mZ2(x.mZ2), GZ2(x.GZ2), lastCont(x.lastCont), lastBW(x.lastBW) {} MEqq2gZ2ll::~MEqq2gZ2ll() {} unsigned int MEqq2gZ2ll::orderInAlphaS() const { return 0; } unsigned int MEqq2gZ2ll::orderInAlphaEW() const { return 2; } void MEqq2gZ2ll::getDiagrams() const { tcPDPtr gamma = getParticleData(ParticleID::gamma); tcPDPtr Z0 = getParticleData(ParticleID::Z0); for(int i = 1; i <= maxFlavour(); ++i) { tcPDPtr q = getParticleData(i); tcPDPtr qb = q->CC(); for(long lid = ParticleID::eminus; lid <= ParticleID::tauminus; lid+=2) { tcPDPtr l = getParticleData(lid); tcPDPtr lb = l->CC(); add(new_ptr((Tree2toNDiagram(2), q, qb, 1, gamma, 3, l, 3, lb, -1))); add(new_ptr((Tree2toNDiagram(2), q, qb, 1, Z0, 3, l, 3, lb, -2))); } } } Energy2 MEqq2gZ2ll::scale() const { return sHat(); } double MEqq2gZ2ll::me2() const { Energy2 m2 = meMomenta()[2].mass2(); // Energy2 p1p3 = 0.5*(m2 - tHat()); // Energy2 p1p2 = 0.5*sHat(); Energy2 p1p3 = meMomenta()[0].dot(meMomenta()[2]); Energy2 p1p2 = meMomenta()[0].dot(meMomenta()[1]); Energy4 pt2 = sqr(p1p3); Energy4 pts = p1p3*p1p2; Energy4 ps2 = sqr(p1p2); Energy4 psm = p1p2*m2; int up = abs(mePartonData()[0]->id() + 1)%2; lastCont = (coefs[0 + up]*(pt2 - pts) + coefs[2 + up]*(ps2 + psm))/sqr(sHat()); double intr = 0.25*(coefs[4 + up]*pt2 + coefs[6 + up]*pts + coefs[8 + up]*ps2 + coefs[10 + up]*psm)* (sHat() - mZ2)/(sHat()*(sqr(sHat() - mZ2) + mZ2*GZ2)); lastBW = 0.25*(coefs[12 + up]*pt2 + coefs[14 + up]*pts + coefs[16 + up]*ps2 + coefs[18 + up]*psm)/ (sqr(sHat() - mZ2) + mZ2*GZ2); DVector save; meInfo(save << lastCont << lastBW); return (lastCont + intr + lastBW)*sqr(SM().alphaEM(scale()))/9.0; } Selector MEqq2gZ2ll::diagrams(const DiagramVector & diags) const { if ( lastXCombPtr() ) { lastCont = meInfo()[0]; lastBW = meInfo()[1]; } Selector sel; for ( DiagramIndex i = 0; i < diags.size(); ++i ) { if ( diags[i]->id() == -1 ) sel.insert(lastCont, i); else if ( diags[i]->id() == -2 ) sel.insert(lastBW, i); } return sel; } Selector MEqq2gZ2ll::colourGeometries(tcDiagPtr diag) const { static ColourLines c("1 -2"); Selector sel; sel.insert(1.0, &c); return sel; } IBPtr MEqq2gZ2ll::clone() const { return new_ptr(*this); } IBPtr MEqq2gZ2ll::fullclone() const { return new_ptr(*this); } -void MEqq2gZ2ll::doinit() throw(InitException) { +void MEqq2gZ2ll::doinit() { double C = sqr(4.0*Constants::pi)/3.0; double SW2 = SM().sin2ThetaW(); double SW4 = sqr(SW2); double SW6 = SW2*SW4; double SW8 = SW2*SW6; double CW2 = 1.0 - SW2; coefs[0] = 16.0*C; coefs[1] = 64.0*C; coefs[2] = 8.0*C; coefs[3] = 32.0*C; C /= (CW2*SW2); coefs[4] = 4.0*(32.0*SW4 - 32.0*SW2 + 6.0)*C; coefs[5] = 8.0*(64.0*SW4 - 40.0*SW2 + 6.0)*C; coefs[6] = -4.0*(32.0*SW4 - 32.0*SW2 + 12.0)*C; coefs[7] = -8.0*(64.0*SW4 - 40.0*SW2 + 12.0)*C; coefs[8] = 4.0*(16.0*SW4 - 16.0*SW2 + 6.0)*C; coefs[9] = 8.0*(32.0*SW4 - 20.0*SW2 + 6.0)*C; coefs[10] = 4.0*(16.0*SW4 - 16.0*SW2 + 3.0)*C; coefs[11] = 8.0*(32.0*SW4 - 20.0*SW2 + 3.0)*C; C /= (CW2*SW2); coefs[12] = ( 64.0*SW8 - 128.0*SW6 + 128.0*SW4 - 48.0*SW2 + 9.0)*C; coefs[13] = (256.0*SW8 - 320.0*SW6 + 200.0*SW4 - 60.0*SW2 + 9.0)*C; coefs[14] = -( 64.0*SW8 - 128.0*SW6 + 176.0*SW4 - 96.0*SW2 + 18.0)*C; coefs[15] = -(256.0*SW8 - 320.0*SW6 + 296.0*SW4 - 120.0*SW2 + 18.0)*C; coefs[16] = ( 32.0*SW8 - 64.0*SW6 + 88.0*SW4 - 48.0*SW2 + 9.0)*C; coefs[17] = (128.0*SW8 - 160.0*SW6 + 148.0*SW4 - 60.0*SW2 + 9.0)*C; coefs[18] = ( 32.0*SW8 - 64.0*SW6 + 28.0*SW4 - 6.0*SW2)*C; coefs[19] = (128.0*SW8 - 160.0*SW6 + 64.0*SW4 - 12.0*SW2)*C; tcPDPtr Z0 = getParticleData(ParticleID::Z0); mZ2 = sqr(Z0->mass()); GZ2 = sqr(Z0->width()); ME2to2QCD::doinit(); } void MEqq2gZ2ll::persistentOutput(PersistentOStream & os) const { os << coefs << ounit(mZ2, GeV2) << ounit(GZ2, GeV2) << lastCont << lastBW; } void MEqq2gZ2ll::persistentInput(PersistentIStream & is, int) { is >> coefs >> iunit(mZ2, GeV2) >> iunit(GZ2, GeV2) >> lastCont >> lastBW; } ClassDescription MEqq2gZ2ll::initMEqq2gZ2ll; void MEqq2gZ2ll::Init() { static ClassDocumentation documentation ("The ThePEG::MEqq2gZ2ll class implements the full" "\\f$q\\bar{q}\\rightarrow\\gamma/Z^0\\rightarrow\\ell^+\\ell^-\\f$ " "matrix element including the interference terms."); } diff --git a/src/MEqq2gZ2ll.h b/src/MEqq2gZ2ll.h --- a/src/MEqq2gZ2ll.h +++ b/src/MEqq2gZ2ll.h @@ -1,128 +1,128 @@ // -*- C++ -*- #ifndef ThePEG_MEqq2gZ2ll_H #define ThePEG_MEqq2gZ2ll_H // // This is the declaration of the MEqq2gZ2ll class. // // CLASSDOC SUBSECTION Description: // // The MEqq2gZ2ll class implements the // e+e- -> gamma/Z0 -> // q+qbar matrix element. Both the continuum and // Z0 pole term as well as the interference term is // included. Although not a strict QCD matrix element the cass // inherits from ME2to2Base, mainly to inherit the // parameter for the number of active quark flavours. // // CLASSDOC SUBSECTION See also: // // ME2to2QCD.h. // #include "ThePEG/MatrixElement/ME2to2QCD.h" using namespace ThePEG; namespace Herwig { class MEqq2gZ2ll: public ME2to2QCD { public: MEqq2gZ2ll(); MEqq2gZ2ll(const MEqq2gZ2ll &); virtual ~MEqq2gZ2ll(); // Standard ctors and dtor public: virtual unsigned int orderInAlphaS() const; virtual unsigned int orderInAlphaEW() const; // Return the order in respective couplings in which this matrix // element is given. Returns 0 and 2 respectively. virtual double me2() const; // Return the matrix element for the kinematical configuation // previously provided by the last call to setKinematics(). virtual void getDiagrams() const; // Add all possible diagrams with the add() function. virtual Selector colourGeometries(tcDiagPtr diag) const; // Return a Selector with possible colour geometries for the selected // diagram weighted by their relative probabilities. virtual Selector diagrams(const DiagramVector &) const; // Weight the given diagrams with their relative probabilities. virtual Energy2 scale() const; // Return the scale associated with the last set phase space point. public: void persistentOutput(PersistentOStream &) const; void persistentInput(PersistentIStream &, int); // Standard functions for writing and reading from persistent streams. static void Init(); // Standard Init function used to initialize the interface. protected: virtual IBPtr clone() const; virtual IBPtr fullclone() const; // Standard clone methods - virtual void doinit() throw(InitException); + virtual void doinit(); // Standard Interfaced virtual functions. protected: vector coefs; // Constants for the different terms set from the StandardModel in // the init() function. Energy2 mZ2; Energy2 GZ2; // The mass squared and width squared of the Z0. mutable double lastCont; mutable double lastBW; // The last continuum and Breit-Wigner terms to be used to select // primary diagram. private: static ClassDescription initMEqq2gZ2ll; MEqq2gZ2ll & operator=(const MEqq2gZ2ll &); // Private and non-existent assignment operator. }; } namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ template <> struct BaseClassTrait: public ClassTraitsType { typedef ME2to2QCD NthBase; }; template <> struct ClassTraits : public ClassTraitsBase { static string className() { return "Herwig::MEqq2gZ2ll"; } static string library() { return "MEqq2gZ2ll.so"; } }; /** @endcond */ } #include "MEqq2gZ2ll.icc" #endif /* ThePEG_MEqq2gZ2ll_H */