Page MenuHomeHEPForge

No OneTemporary

diff --git a/DipoleShower/Base/DipoleSplittingInfo.cc b/DipoleShower/Base/DipoleSplittingInfo.cc
--- a/DipoleShower/Base/DipoleSplittingInfo.cc
+++ b/DipoleShower/Base/DipoleSplittingInfo.cc
@@ -1,158 +1,157 @@
// -*- C++ -*-
//
// DipoleSplittingInfo.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the DipoleIndex and DipoleSplittingInfo classes.
//
#include "DipoleSplittingInfo.h"
-#include "ThePEG/Handlers/StandardXComb.h"
#include <iterator>
using std::ostream_iterator;
using namespace Herwig;
DipoleIndex::DipoleIndex()
: theInitialStateEmitter(false), theInitialStateSpectator(false) {}
DipoleIndex::DipoleIndex(tcPDPtr newEmitter, tcPDPtr newSpectator,
const PDF& newEmitterPDF, const PDF& newSpectatorPDF)
: theEmitterData(newEmitter), theInitialStateEmitter(newEmitterPDF.pdf()),
theEmitterPDF(newEmitterPDF),
theSpectatorData(newSpectator), theInitialStateSpectator(newSpectatorPDF.pdf()),
theSpectatorPDF(newSpectatorPDF) {}
bool DipoleIndex::operator ==(const DipoleIndex& x) const {
return
theEmitterData == x.theEmitterData &&
theInitialStateEmitter == x.theInitialStateEmitter &&
theEmitterPDF == x.theEmitterPDF &&
theSpectatorData == x.theSpectatorData &&
theInitialStateSpectator == x.theInitialStateSpectator &&
theSpectatorPDF == x.theSpectatorPDF;
}
bool DipoleIndex::operator <(const DipoleIndex& x) const {
if ( theEmitterData == x.theEmitterData ) {
if ( theInitialStateEmitter == x.theInitialStateEmitter ) {
if ( theEmitterPDF == x.theEmitterPDF ) {
if ( theSpectatorData == x.theSpectatorData ) {
if ( theInitialStateSpectator == x.theInitialStateSpectator ) {
return theSpectatorPDF < x.theSpectatorPDF;
}
return theInitialStateSpectator < x.theInitialStateSpectator;
}
return theSpectatorData < x.theSpectatorData;
}
return theEmitterPDF < x.theEmitterPDF;
}
return theInitialStateEmitter < x.theInitialStateEmitter;
}
return theEmitterData < x.theEmitterData;
}
void DipoleIndex::swap() {
std::swap(theEmitterData,theSpectatorData);
std::swap(theInitialStateEmitter,theInitialStateSpectator);
std::swap(theEmitterPDF,theSpectatorPDF);
}
pair<DipoleIndex,DipoleIndex> DipoleIndex::split(tcPDPtr emm) const {
DipoleIndex first(emitterData(),emm,emitterPDF(),PDF());
DipoleIndex second(emm,spectatorData(),PDF(),spectatorPDF());
return make_pair(first,second);
}
void DipoleIndex::print(ostream& os) const {
os << "[" << emitterData()->PDGName();
if ( emitterPDF().pdf() ) {
os << "<-" << emitterPDF().particle()->PDGName()
<< "(" << emitterPDF().pdf() << ")";
}
os << "," << spectatorData()->PDGName();
if ( spectatorPDF().pdf() ) {
os << "<-" << spectatorPDF().particle()->PDGName()
<< "(" << spectatorPDF().pdf() << ")";
}
os << "]";
os << flush;
}
DipoleSplittingInfo::DipoleSplittingInfo()
: theConfiguration(false,false),
theSpectatorConfiguration(false,false),
theScale(0.0*GeV),
theEmitterX(1.0), theSpectatorX(1.0),
theHardPt(0.0*GeV), theLastPt(0.0*GeV),
theLastZ(0.0), theLastPhi(0.0), theLastEmitterZ(0.0),
theLastSpectatorZ(0.0), theLastValue(0.0),
theStoppedEvolving(false) {}
void DipoleSplittingInfo::fill(const DipoleSplittingInfo& other) {
*this = other;
}
void DipoleSplittingInfo::print(ostream& os) const {
os << "--- DipoleSplittingInfo --------------------------------------------------------\n";
os << " index = " << theIndex << "\n";
os << " configuration = (" << theConfiguration.first << "," << theConfiguration.second << ")\n"
<< " momentum fractions = [" << theEmitterX << "," << theSpectatorX << "]\n"
<< " generated starting from hard pt/GeV = " << theHardPt/GeV << "\n";
if ( theEmitterData && theEmissionData && theSpectatorData ) {
os << " splitting products = [(" << theEmitterData->PDGName()
<< "," << theEmissionData->PDGName() << "),"
<< theSpectatorData->PDGName() << "]\n";
} else {
os << " splitting products not available.\n";
}
if ( theSplittingKinematics ) {
os << " kinematic variables associated to '" << theSplittingKinematics->name() << "':\n"
<< " scale = " << (theScale/GeV)
<< " pt/GeV = " << (theLastPt/GeV) << " z = " << theLastZ << " phi = " << theLastPhi << "\n"
<< " emitter z = " << theLastEmitterZ << " spectator z = " << theLastSpectatorZ << "\n"
<< " splitting kernel value = " << theLastValue << "\n"
<< " further parameters = ";
copy(theLastSplittingParameters.begin(),theLastSplittingParameters.end(),ostream_iterator<double>(os," "));
os << "\n the splitting " << (theStoppedEvolving ? "terminated " : "did not terminate ") << "the evolution\n";
} else {
os << " No kinematic variables have been generated yet.\n";
}
if ( theEmitter && theSpectator && theSplitEmitter && theSplitSpectator && theEmission ) {
os << " the splitting has been performed:\n"
<< " emitter before emission:\n" << (*theEmitter)
<< " spectator before emission:\n" << (*theSpectator)
<< " emitter after emission:\n" << (*theSplitEmitter)
<< " emission:\n" << (*theEmission)
<< " spectator after emission:\n" << (*theSplitSpectator);
} else {
os << " the splitting has not yet been performed.\n";
}
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
diff --git a/DipoleShower/Base/DipoleSplittingInfo.h b/DipoleShower/Base/DipoleSplittingInfo.h
--- a/DipoleShower/Base/DipoleSplittingInfo.h
+++ b/DipoleShower/Base/DipoleSplittingInfo.h
@@ -1,617 +1,616 @@
// -*- C++ -*-
//
// DipoleSplittingInfo.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_DipoleSplittingInfo_H
#define HERWIG_DipoleSplittingInfo_H
//
// This is the declaration of the DipoleIndex and DipoleSplittingInfo classes.
//
#include "ThePEG/PDF/PDF.h"
#include "ThePEG/PDT/ParticleData.h"
-#include "ThePEG/Handlers/StandardXComb.fh"
#include "Herwig++/DipoleShower/Kinematics/DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
class DipoleSplittingKinematics;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief DipoleIndex is used to index splitting generators
* for a particular dipole.
*
*/
class DipoleIndex {
public:
/**
* The default constructor.
*/
DipoleIndex();
/**
* The standard constructor
*/
DipoleIndex(tcPDPtr newEmitter, tcPDPtr newSpectator,
const PDF& newEmitterPDF = PDF(), const PDF& newSpectatorPDF = PDF());
public:
/**
* Compare for equality.
*/
bool operator ==(const DipoleIndex& x) const;
/**
* Compare for ordering.
*/
bool operator <(const DipoleIndex& x) const;
/**
* Swap emitter and spectator.
*/
void swap();
/**
* Produce a pair of dipole indices given
* a particle data object for the emission.
* The ME correction is ignored in the children.
* The emission is inserted between the emitter
* and spectator, being a spectator in the first
* dipole index containing the original emitter,
* and an emitter in the second dipole, containing
* the original spectator.
*/
pair<DipoleIndex,DipoleIndex> split(tcPDPtr) const;
public:
/**
* Return the emitter particle data object.
*/
tcPDPtr emitterData() const { return theEmitterData; }
/**
* Return true, if the emitter is an incoming parton
*/
bool initialStateEmitter() const { return theInitialStateEmitter; }
/**
* Return the PDF object associated with the emitter
*/
const PDF& emitterPDF() const { return theEmitterPDF; }
/**
* Return the spectator particle data object.
*/
tcPDPtr spectatorData() const { return theSpectatorData; }
/**
* Return true, if the spectator is an incoming parton
*/
bool initialStateSpectator() const { return theInitialStateSpectator; }
/**
* Return the PDF object associated with the spectator
*/
const PDF& spectatorPDF() const { return theSpectatorPDF; }
public:
/**
* Put information to ostream
*/
void print(ostream&) const;
private:
/**
* The particle data object of the emitter.
*/
tcPDPtr theEmitterData;
/**
* Wether or not the emitter is an incoming parton.
*/
bool theInitialStateEmitter;
/**
* The PDF object for the emitter.
*/
PDF theEmitterPDF;
/**
* The particle data object of the spectator.
*/
tcPDPtr theSpectatorData;
/**
* Wether or not the spectator is an incoming parton.
*/
bool theInitialStateSpectator;
/**
* The PDF object for the spectator.
*/
PDF theSpectatorPDF;
};
inline ostream& operator << (ostream& os, const DipoleIndex& di) {
di.print(os);
return os;
}
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief DipoleSplittingInfo contains all parameters to generate a full
* dipole splitting.
*
*/
class DipoleSplittingInfo {
public:
/**
* The default constructor.
*/
DipoleSplittingInfo();
/**
* Destructor
*/
virtual ~DipoleSplittingInfo() {}
public:
/**
* Assign data from another splitting info
*/
void fill(const DipoleSplittingInfo&);
public:
/**
* Return the dipole index
*/
const DipoleIndex& index() const { return theIndex; }
/**
* Return which of the particles
* in the dipole should be considered emitter (true)
* and spectator (false)
*/
const pair<bool,bool>& configuration() const { return theConfiguration; }
/**
* Get the configuration marking the spectator
*/
const pair<bool,bool>& spectatorConfiguration() const { return theSpectatorConfiguration; }
/**
* Return the particle data object of the emitter
* after the splitting.
*/
tcPDPtr emitterData() const { return theEmitterData; }
/**
* Return the particle data object of the emission
* after the splitting.
*/
tcPDPtr emissionData() const { return theEmissionData; }
/**
* Return the particle data object of the spectator
* after the splitting.
*/
tcPDPtr spectatorData() const { return theSpectatorData; }
/**
* Return the momentum fraction of the emitter.
*/
double emitterX() const { return theEmitterX; }
/**
* Return the momentum fraction of the spectator.
*/
double spectatorX() const { return theSpectatorX; }
public:
/**
* Return a pointer to the DipoleSplittingKinematics object
* which is to be used to perform the splitting.
*/
Ptr<DipoleSplittingKinematics>::tptr splittingKinematics() const { return theSplittingKinematics; }
/**
* Return the dipole scale
*/
Energy scale() const { return theScale; }
/**
* Return the pt below which this
* splitting has been generated.
*/
Energy hardPt() const { return theHardPt; }
/**
* Return the last generated pt
*/
Energy lastPt() const { return theLastPt; }
/**
* Return the last generated momentum fraction.
*/
double lastZ() const { return theLastZ; }
/**
* Return the last generated azimuthal angle.
*/
double lastPhi() const { return theLastPhi; }
/**
* Return the momentum fraction, by which the emitter's
* momentum fraction should be divided after the splitting.
*/
double lastEmitterZ() const { return theLastEmitterZ; }
/**
* Return the momentum fraction, by which the spectator's
* momentum fraction should be divided after the splitting.
*/
double lastSpectatorZ() const { return theLastSpectatorZ; }
/**
* Return any additional parameters needed to
* evaluate the splitting kernel or to generate the
* full splitting.
*/
const vector<double>& lastSplittingParameters() const { return theLastSplittingParameters; }
/**
* Return true, if this splitting will terminate
* the evolution of the dipole considered.
*/
bool stoppedEvolving() const { return theStoppedEvolving; }
public:
/**
* Set the index.
*/
void index(const DipoleIndex& ind) { theIndex = ind; }
/**
* Set the DipoleSplittingKinematics object
*/
void splittingKinematics(Ptr<DipoleSplittingKinematics>::tptr newSplittingKinematics) {
theSplittingKinematics = newSplittingKinematics;
}
/**
* Set the particle data object of the emitter
* after the splitting.
*/
void emitterData(tcPDPtr p) { theEmitterData = p; }
/**
* Set the particle data object of the emission
* after the splitting.
*/
void emissionData(tcPDPtr p) { theEmissionData = p; }
/**
* Set the particle data object of the spectator
* after the splitting.
*/
void spectatorData(tcPDPtr p) { theSpectatorData = p; }
/**
* Set the dipole scale
*/
void scale(Energy s) { theScale = s; }
/**
* Set the emitter's momentum fraction
*/
void emitterX(double x) { theEmitterX = x; }
/**
* Set the spectator's momentum fraction
*/
void spectatorX(double x) { theSpectatorX = x; }
/**
* Set the pt below which this
* splitting has been generated.
*/
void hardPt(Energy p) { theHardPt = p; }
/**
* Set the last generated pt
*/
void lastPt(Energy p) { theLastPt = p; }
/**
* Set the last generated momentum fraction.
*/
void lastZ(double z) { theLastZ = z; }
/**
* Set the last generated azimuthal angle.
*/
void lastPhi(double p) { theLastPhi = p; }
/**
* Set the momentum fraction, by which the emitter's
* momentum fraction should be divided after the splitting.
*/
void lastEmitterZ(double z) { theLastEmitterZ = z; }
/**
* Set the momentum fraction, by which the spectator's
* momentum fraction should be divided after the splitting.
*/
void lastSpectatorZ(double z) { theLastSpectatorZ = z; }
/**
* Return the last splitting kernel value encountered.
*/
double lastValue() const { return theLastValue; }
/**
* Set the last splitting kernel value encountered.
*/
void lastValue(double v) { theLastValue = v; }
/**
* Set the last splitting parameters.
*/
void lastSplittingParameters(const vector<double>& p) { theLastSplittingParameters = p; }
/**
* Access the splitting parameters
*/
vector<double>& splittingParameters() { return theLastSplittingParameters; }
/**
* Indicate that this splitting will terminate
* the evolution of the dipole considered.
*/
void didStopEvolving() { theStoppedEvolving = true; }
/**
* Indicate that this splitting will not terminate
* the evolution of the dipole considered.
*/
void continuesEvolving() { theStoppedEvolving = false; }
/**
* Reset the configuration.
*/
void configuration(const pair<bool,bool>& newConfig) { theConfiguration = newConfig; }
/**
* Set the configuration marking the spectator
*/
void spectatorConfiguration(const pair<bool,bool>& conf) { theSpectatorConfiguration = conf; }
public:
/**
* Set a pointer to the emitter parton before emission.
*/
void emitter(tPPtr newEmitter) { theEmitter = newEmitter; }
/**
* Set a pointer to the spectator parton before emission.
*/
void spectator(tPPtr newSpectator) { theSpectator = newSpectator; }
/**
* Set a pointer to the emitter parton after emission.
*/
void splitEmitter(tPPtr newEmitter) { theSplitEmitter = newEmitter; }
/**
* Set a pointer to the spectator parton after emission.
*/
void splitSpectator(tPPtr newSpectator) { theSplitSpectator = newSpectator; }
/**
* Set a pointer to the emitted parton.
*/
void emission(tPPtr newEmission) { theEmission = newEmission; }
/**
* Return a pointer to the emitter parton before emission.
*/
tPPtr emitter() const { return theEmitter; }
/**
* Return a pointer to the spectator parton before emission.
*/
tPPtr spectator() const { return theSpectator; }
/**
* Return a pointer to the emitter parton after emission.
*/
tPPtr splitEmitter() const { return theSplitEmitter; }
/**
* Return a pointer to the spectator parton after emission.
*/
tPPtr splitSpectator() const { return theSplitSpectator; }
/**
* Return a pointer to the emitted parton.
*/
tPPtr emission() const { return theEmission; }
public:
/**
* Put information to ostream
*/
void print(ostream&) const;
private:
/**
* The DipoleIndex associated
* with this splitting.
*/
DipoleIndex theIndex;
/**
* Flags indicateing which of the particles
* in the dipole should be considered emitter (true)
* and spectator (false)
*/
pair<bool,bool> theConfiguration;
/**
* The configuration marking the spectator
*/
pair<bool,bool> theSpectatorConfiguration;
/**
* The particle data object of the emitter
* after the splitting.
*/
tcPDPtr theEmitterData;
/**
* The particle data object of the emission
* after the splitting.
*/
tcPDPtr theEmissionData;
/**
* The particle data object of the spectator
* after the splitting.
*/
tcPDPtr theSpectatorData;
/**
* A pointer to the DipoleSplittingKinematics object
* which is to be used to perform the splitting.
*/
Ptr<DipoleSplittingKinematics>::tptr theSplittingKinematics;
/**
* The scale for this dipole.
*/
Energy theScale;
/**
* The momentum fraction of the emitter.
*/
double theEmitterX;
/**
* The momentum fraction of the spectator.
*/
double theSpectatorX;
/**
* The pt below which this splitting has
* been generated.
*/
Energy theHardPt;
/**
* The last generated pt
*/
Energy theLastPt;
/**
* The last generated momentum fraction.
*/
double theLastZ;
/**
* The last generated azimuthal angle.
*/
double theLastPhi;
/**
* The momentum fraction, by which the emitter's
* momentum fraction should be divided after the splitting.
*/
double theLastEmitterZ;
/**
* The momentum fraction, by which the spectator's
* momentum fraction should be divided after the splitting.
*/
double theLastSpectatorZ;
/**
* The last splitting kernel value encountered.
*/
double theLastValue;
/**
* Any additional parameters needed to
* evaluate the splitting kernel or to generate the
* full splitting.
*/
vector<double> theLastSplittingParameters;
/**
* True, if this splitting will terminate
* the evolution of the dipole considered.
*/
bool theStoppedEvolving;
/**
* A pointer to the emitter parton before emission.
*/
PPtr theEmitter;
/**
* A pointer to the spectator parton before emission.
*/
PPtr theSpectator;
/**
* A pointer to the emitter parton after emission.
*/
PPtr theSplitEmitter;
/**
* A pointer to the spectator parton after emission.
*/
PPtr theSplitSpectator;
/**
* A pointer to the emitted parton.
*/
PPtr theEmission;
};
inline ostream& operator << (ostream& os, const DipoleSplittingInfo& di) {
di.print(os);
return os;
}
}
#endif /* HERWIG_DipoleSplittingInfo_H */
diff --git a/DipoleShower/DipoleShowerHandler.cc b/DipoleShower/DipoleShowerHandler.cc
--- a/DipoleShower/DipoleShowerHandler.cc
+++ b/DipoleShower/DipoleShowerHandler.cc
@@ -1,1145 +1,1148 @@
// -*- C++ -*-
//
// DipoleShowerHandler.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the DipoleShowerHandler class.
//
#include <config.h>
#include "DipoleShowerHandler.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
// include theses to have complete types
#include "Herwig++/Shower/Base/Evolver.h"
#include "Herwig++/Shower/Base/ShowerParticle.h"
#include "Herwig++/PDF/MPIPDF.h"
#include "Herwig++/PDF/MinBiasPDF.h"
#include "Herwig++/Shower/Base/ShowerTree.h"
#include "Herwig++/Shower/Base/KinematicsReconstructor.h"
#include "Herwig++/Shower/Base/PartnerFinder.h"
#include "Herwig++/PDF/HwRemDecayer.h"
#include "Herwig++/DipoleShower/Utility/DipolePartonSplitter.h"
#include "Herwig++/MatrixElement/Matchbox/Base/SubtractedME.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
using namespace Herwig;
bool DipoleShowerHandler::firstWarn = true;
DipoleShowerHandler::DipoleShowerHandler()
: ShowerHandler(), chainOrderVetoScales(true),
nEmissions(0), discardNoEmissions(false), firstMCatNLOEmission(false),
doFSR(true), doISR(true), realignmentScheme(0),
hardFirstEmission(false),
verbosity(0), printEvent(0), nTries(0),
didRadiate(false), didRealign(false),
theRenormalizationScaleFreeze(1.*GeV),
theFactorizationScaleFreeze(2.*GeV),
isMCatNLOSEvent(false),
isMCatNLOHEvent(false), theDoCompensate(false),
maxPtIsMuF(false), theFreezeGrid(500000) {}
DipoleShowerHandler::~DipoleShowerHandler() {}
IBPtr DipoleShowerHandler::clone() const {
return new_ptr(*this);
}
IBPtr DipoleShowerHandler::fullclone() const {
return new_ptr(*this);
}
tPPair DipoleShowerHandler::cascade(tSubProPtr sub, XCPtr,
Energy optHardPt, Energy optCutoff) {
useMe();
prepareCascade(sub);
if ( !doFSR && ! doISR )
return sub->incoming();
eventRecord().clear();
eventRecord().prepare(sub,dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr()),pdfs());
if ( eventRecord().outgoing().empty() && !doISR )
return sub->incoming();
if ( !eventRecord().incoming().first->coloured() &&
!eventRecord().incoming().second->coloured() &&
!doFSR )
return sub->incoming();
nTries = 0;
while ( true ) {
try {
didRadiate = false;
didRealign = false;
isMCatNLOSEvent = false;
isMCatNLOHEvent = false;
- Ptr<SubtractedME>::tptr subme =
- dynamic_ptr_cast<Ptr<SubtractedME>::tptr>(eventRecord().xcombPtr()->matrixElement());
- Ptr<MatchboxMEBase>::tptr me =
- dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(eventRecord().xcombPtr()->matrixElement());
- Ptr<SubtractionDipole>::tptr dipme =
- dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(eventRecord().xcombPtr()->matrixElement());
+ if ( eventRecord().xcombPtr() ) {
+ Ptr<SubtractedME>::tptr subme =
+ dynamic_ptr_cast<Ptr<SubtractedME>::tptr>(eventRecord().xcombPtr()->matrixElement());
+ Ptr<MatchboxMEBase>::tptr me =
+ dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(eventRecord().xcombPtr()->matrixElement());
+ Ptr<SubtractionDipole>::tptr dipme =
+ dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(eventRecord().xcombPtr()->matrixElement());
- if ( subme ) {
- if ( subme->showerApproximation() ) {
- // don't do this for POWHEG-type corrections
- if ( !subme->showerApproximation()->needsSplittingGenerator() ) {
- theShowerApproximation = subme->showerApproximation();
- if ( subme->realShowerSubtraction() )
- isMCatNLOHEvent = true;
- else if ( subme->virtualShowerSubtraction() )
+
+ if ( subme ) {
+ if ( subme->showerApproximation() ) {
+ // don't do this for POWHEG-type corrections
+ if ( !subme->showerApproximation()->needsSplittingGenerator() ) {
+ theShowerApproximation = subme->showerApproximation();
+ if ( subme->realShowerSubtraction() )
+ isMCatNLOHEvent = true;
+ else if ( subme->virtualShowerSubtraction() )
+ isMCatNLOSEvent = true;
+ }
+ }
+ } else if ( me ) {
+ if ( me->factory()->showerApproximation() ) {
+ if ( !me->factory()->showerApproximation()->needsSplittingGenerator() ) {
+ theShowerApproximation = me->factory()->showerApproximation();
isMCatNLOSEvent = true;
+ }
}
}
- } else if ( me ) {
- if ( me->factory()->showerApproximation() ) {
- if ( !me->factory()->showerApproximation()->needsSplittingGenerator() ) {
- theShowerApproximation = me->factory()->showerApproximation();
- isMCatNLOSEvent = true;
- }
+
+ string error = "Inconsistent hard emission set-up in DipoleShowerHandler::cascade. ";
+ if (evolver()->hardEmissionMode()==1 || evolver()->hardEmissionMode()==3 )
+ throw Exception() << error
+ << "Cannot generate POWHEG corrections "
+ << "for particle decays using DipoleShowerHandler. "
+ << "Check value of Evolver:HardEmissionMode."
+ << Exception::runerror;
+ if ( ( isMCatNLOSEvent || isMCatNLOHEvent ) && evolver()->hardEmissionMode()==2)
+ throw Exception() << error
+ << "Cannot generate POWHEG matching with MC@NLO shower approximation. "
+ << "Add 'set Evolver:HardEmissionMode 0' to input file."
+ << Exception::runerror;
+ if (me && me->factory()->showerApproximation()){
+ if(me->factory()->showerApproximation()->needsTruncatedShower())
+ throw Exception() << error
+ << "No truncated shower needed with DipoleShowerHandler. Add "
+ << "'set MEMatching:TruncatedShower No' to input file."
+ << Exception::runerror;
+ if (!( isMCatNLOSEvent || isMCatNLOHEvent ) &&
+ evolver()->hardEmissionMode()==0 && firstWarn){
+ firstWarn=false;
+ throw Exception() << error
+ << "Evolver:HardEmissionMode will be set to 'MatchboxPOWHEG'"
+ << Exception::warning;
+ }
}
- }
-
- string error = "Inconsistent hard emission set-up in DipoleShowerHandler::cascade. ";
- if (evolver()->hardEmissionMode()==1 || evolver()->hardEmissionMode()==3 )
- throw Exception() << error
- << "Cannot generate POWHEG corrections "
- << "for particle decays using DipoleShowerHandler. "
- << "Check value of Evolver:HardEmissionMode."
- << Exception::runerror;
- if ( ( isMCatNLOSEvent || isMCatNLOHEvent ) && evolver()->hardEmissionMode()==2)
- throw Exception() << error
- << "Cannot generate POWHEG matching with MC@NLO shower approximation. "
- << "Add 'set Evolver:HardEmissionMode 0' to input file."
- << Exception::runerror;
- if (me && me->factory()->showerApproximation()){
- if(me->factory()->showerApproximation()->needsTruncatedShower())
- throw Exception() << error
- << "No truncated shower needed with DipoleShowerHandler. Add "
- << "'set MEMatching:TruncatedShower No' to input file."
- << Exception::runerror;
- if (!( isMCatNLOSEvent || isMCatNLOHEvent ) &&
- evolver()->hardEmissionMode()==0 && firstWarn){
+ else if (subme && subme->factory()->showerApproximation()){
+ if(subme->factory()->showerApproximation()->needsTruncatedShower())
+ throw Exception() << error
+ << "No truncated shower needed with DipoleShowerHandler. Add "
+ << "'set MEMatching:TruncatedShower No' to input file."
+ << Exception::runerror;
+ if (!( isMCatNLOSEvent || isMCatNLOHEvent ) &&
+ evolver()->hardEmissionMode()==0 && firstWarn){
+ firstWarn=false;
+ throw Exception() << error
+ << "Evolver:HardEmissionMode will be set to 'MatchboxPOWHEG'"
+ << Exception::warning;
+ }
+ }
+ else if (dipme && evolver()->hardEmissionMode() == 0 && firstWarn){
firstWarn=false;
throw Exception() << error
<< "Evolver:HardEmissionMode will be set to 'MatchboxPOWHEG'"
<< Exception::warning;
- }
+ }
+ else if (!dipme && evolver()->hardEmissionMode()==2 &&
+ ShowerHandler::currentHandler()->firstInteraction())
+ throw Exception() << error
+ << "POWHEG matching requested for LO events. Include "
+ << "'set Factory:ShowerApproximation MEMatching' in input file."
+ << Exception::runerror;
+
}
- else if (subme && subme->factory()->showerApproximation()){
- if(subme->factory()->showerApproximation()->needsTruncatedShower())
- throw Exception() << error
- << "No truncated shower needed with DipoleShowerHandler. Add "
- << "'set MEMatching:TruncatedShower No' to input file."
- << Exception::runerror;
- if (!( isMCatNLOSEvent || isMCatNLOHEvent ) &&
- evolver()->hardEmissionMode()==0 && firstWarn){
- firstWarn=false;
- throw Exception() << error
- << "Evolver:HardEmissionMode will be set to 'MatchboxPOWHEG'"
- << Exception::warning;
- }
- }
- else if (dipme && evolver()->hardEmissionMode() == 0 && firstWarn){
- firstWarn=false;
- throw Exception() << error
- << "Evolver:HardEmissionMode will be set to 'MatchboxPOWHEG'"
- << Exception::warning;
- }
- else if (!dipme && evolver()->hardEmissionMode()==2 &&
- ShowerHandler::currentHandler()->firstInteraction())
- throw Exception() << error
- << "POWHEG matching requested for LO events. Include "
- << "'set Factory:ShowerApproximation MEMatching' in input file."
- << Exception::runerror;
- hardScales();
+ hardScales(lastXCombPtr()->lastCentralScale());
if ( verbosity > 1 ) {
generator()->log() << "DipoleShowerHandler starting off:\n";
eventRecord().debugLastEvent(generator()->log());
generator()->log() << flush;
}
unsigned int nEmitted = 0;
if ( firstMCatNLOEmission ) {
if ( !isMCatNLOHEvent )
nEmissions = 1;
else
nEmissions = 0;
}
if ( !firstMCatNLOEmission ) {
doCascade(nEmitted,optHardPt,optCutoff);
if ( discardNoEmissions ) {
if ( !didRadiate )
throw Veto();
if ( nEmissions )
if ( nEmissions < nEmitted )
throw Veto();
}
} else {
if ( nEmissions == 1 )
doCascade(nEmitted,optHardPt,optCutoff);
}
if ( intrinsicPtGenerator ) {
if ( eventRecord().incoming().first->coloured() &&
eventRecord().incoming().second->coloured() ) {
SpinOneLorentzRotation rot =
intrinsicPtGenerator->kick(eventRecord().incoming(),
eventRecord().intermediates());
eventRecord().transform(rot);
}
}
didRealign = realign();
constituentReshuffle();
break;
} catch (RedoShower&) {
if ( ++nTries > maxtry() )
throw ShowerTriesVeto(maxtry());
eventRecord().clear();
eventRecord().prepare(sub,dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr()),pdfs());
continue;
} catch (...) {
throw;
}
}
return eventRecord().fillEventRecord(newStep(),firstInteraction(),didRealign);
}
void DipoleShowerHandler::constituentReshuffle() {
if ( constituentReshuffler ) {
constituentReshuffler->reshuffle(eventRecord().outgoing(),
eventRecord().incoming(),
eventRecord().intermediates());
}
}
-void DipoleShowerHandler::hardScales() {
+void DipoleShowerHandler::hardScales(Energy2 muf) {
Energy maxPt = generator()->maximumCMEnergy();
bool restrictPhasespace = !hardFirstEmission;
- if ( !restrictPhasespace ) {
- assert(eventRecord().xcombPtr());
+ if ( !restrictPhasespace && eventRecord().xcombPtr() ) {
Ptr<SubtractedME>::tptr subme =
dynamic_ptr_cast<Ptr<SubtractedME>::tptr>(eventRecord().xcombPtr()->matrixElement());
if ( subme )
if ( subme->realShowerSubtraction() )
restrictPhasespace = true;
}
if ( !maxPtIsMuF || !firstInteraction() ) {
if ( (eventRecord().incoming().first->coloured() ||
eventRecord().incoming().second->coloured()) &&
restrictPhasespace ) {
if ( !eventRecord().outgoing().empty() ) {
for ( PList::const_iterator p = eventRecord().outgoing().begin();
p != eventRecord().outgoing().end(); ++p )
maxPt = min(maxPt,(**p).momentum().mt());
} else {
assert(!eventRecord().hard().empty());
Lorentz5Momentum phard(ZERO,ZERO,ZERO,ZERO);
for ( PList::const_iterator p = eventRecord().hard().begin();
p != eventRecord().hard().end(); ++p )
phard += (**p).momentum();
Energy mhard = phard.m();
maxPt = mhard;
}
maxPt *= hardScaleFactor();
}
} else {
- maxPt = hardScaleFactor()*sqrt(eventRecord().xcombPtr()->lastCentralScale());
+ maxPt = hardScaleFactor()*sqrt(muf);
}
for ( list<DipoleChain>::iterator ch = eventRecord().chains().begin();
ch != eventRecord().chains().end(); ++ch ) {
Energy minVetoScale = -1.*GeV;
for ( list<Dipole>::iterator dip = ch->dipoles().begin();
dip != ch->dipoles().end(); ++dip ) {
// max scale per config
Energy maxFirst = 0.0*GeV;
Energy maxSecond = 0.0*GeV;
for ( vector<Ptr<DipoleSplittingKernel>::ptr>::iterator k =
kernels.begin(); k != kernels.end(); ++k ) {
pair<bool,bool> conf = make_pair(true,false);
if ( (**k).canHandle(dip->index(conf)) ) {
Energy scale =
evolutionOrdering()->hardScale(dip->emitter(conf),dip->spectator(conf),
dip->emitterX(conf),dip->spectatorX(conf),
**k,dip->index(conf));
maxFirst = max(maxFirst,scale);
}
conf = make_pair(false,true);
if ( (**k).canHandle(dip->index(conf)) ) {
Energy scale =
evolutionOrdering()->hardScale(dip->emitter(conf),dip->spectator(conf),
dip->emitterX(conf),dip->spectatorX(conf),
**k,dip->index(conf));
maxSecond = max(maxSecond,scale);
}
}
if ( dip->leftParticle()->vetoScale() >= ZERO ) {
maxFirst = min(maxFirst,sqrt(dip->leftParticle()->vetoScale()));
if ( minVetoScale >= ZERO )
minVetoScale = min(minVetoScale,sqrt(dip->leftParticle()->vetoScale()));
else
minVetoScale = sqrt(dip->leftParticle()->vetoScale());
}
if ( dip->rightParticle()->vetoScale() >= ZERO ) {
maxSecond = min(maxSecond,sqrt(dip->rightParticle()->vetoScale()));
if ( minVetoScale >= ZERO )
minVetoScale = min(minVetoScale,sqrt(dip->rightParticle()->vetoScale()));
else
minVetoScale = sqrt(dip->rightParticle()->vetoScale());
}
maxFirst = min(maxPt,maxFirst);
dip->emitterScale(make_pair(true,false),maxFirst);
maxSecond = min(maxPt,maxSecond);
dip->emitterScale(make_pair(false,true),maxSecond);
}
if ( !evolutionOrdering()->independentDipoles() &&
chainOrderVetoScales &&
minVetoScale >= ZERO ) {
for ( list<Dipole>::iterator dip = ch->dipoles().begin();
dip != ch->dipoles().end(); ++dip ) {
dip->leftScale(min(dip->leftScale(),minVetoScale));
dip->rightScale(min(dip->rightScale(),minVetoScale));
}
}
}
}
Energy DipoleShowerHandler::getWinner(DipoleSplittingInfo& winner,
const Dipole& dip,
pair<bool,bool> conf,
Energy optHardPt,
Energy optCutoff) {
return
getWinner(winner,dip.index(conf),
dip.emitterX(conf),dip.spectatorX(conf),
conf,dip.emitter(conf),dip.spectator(conf),
dip.emitterScale(conf),optHardPt,optCutoff);
}
Energy DipoleShowerHandler::getWinner(SubleadingSplittingInfo& winner,
Energy optHardPt,
Energy optCutoff) {
return
getWinner(winner,winner.index(),
winner.emitterX(),winner.spectatorX(),
winner.configuration(),
winner.emitter(),winner.spectator(),
winner.startScale(),optHardPt,optCutoff);
}
Energy DipoleShowerHandler::getWinner(DipoleSplittingInfo& winner,
const DipoleIndex& index,
double emitterX, double spectatorX,
pair<bool,bool> conf,
tPPtr emitter, tPPtr spectator,
Energy startScale,
Energy optHardPt,
Energy optCutoff) {
if ( !index.initialStateEmitter() &&
!doFSR ) {
winner.didStopEvolving();
return 0.0*GeV;
}
if ( index.initialStateEmitter() &&
!doISR ) {
winner.didStopEvolving();
return 0.0*GeV;
}
DipoleSplittingInfo candidate;
candidate.index(index);
candidate.configuration(conf);
candidate.emitterX(emitterX);
candidate.spectatorX(spectatorX);
if ( generators().find(candidate.index()) == generators().end() )
getGenerators(candidate.index());
//
// NOTE -- needs proper fixing at some point
//
// For some very strange reason, equal_range gives back
// key ranges it hasn't been asked for. This particularly
// happens e.g. for FI dipoles of the same kind, but different
// PDF (hard vs MPI PDF). I can't see a reason for this,
// as DipoleIndex properly implements comparison for equality
// and (lexicographic) ordering; for the time being, we
// use equal_range, extented by an explicit check for wether
// the key is indeed what we wanted. See line after (*) comment
// below.
//
pair<GeneratorMap::iterator,GeneratorMap::iterator> gens
= generators().equal_range(candidate.index());
Energy winnerScale = 0.0*GeV;
GeneratorMap::iterator winnerGen = generators().end();
for ( GeneratorMap::iterator gen = gens.first; gen != gens.second; ++gen ) {
// (*) see NOTE above
if ( !(gen->first == candidate.index()) )
continue;
if ( startScale <= gen->second->splittingKinematics()->IRCutoff() )
continue;
Energy dScale =
gen->second->splittingKinematics()->dipoleScale(emitter->momentum(),
spectator->momentum());
// in very exceptional cases happening in DIS
if ( isnan(dScale/GeV ) )
throw RedoShower();
candidate.scale(dScale);
candidate.continuesEvolving();
Energy hardScale = evolutionOrdering()->maxPt(startScale,candidate,*(gen->second->splittingKernel()));
Energy maxPossible =
gen->second->splittingKinematics()->ptMax(candidate.scale(),
candidate.emitterX(), candidate.spectatorX(),
candidate.index(),
*gen->second->splittingKernel());
Energy ircutoff =
optCutoff < gen->second->splittingKinematics()->IRCutoff() ?
gen->second->splittingKinematics()->IRCutoff() :
optCutoff;
if ( maxPossible <= ircutoff ) {
continue;
}
if ( maxPossible >= hardScale )
candidate.hardPt(hardScale);
else {
hardScale = maxPossible;
candidate.hardPt(maxPossible);
}
gen->second->generate(candidate,optHardPt,optCutoff);
Energy nextScale = evolutionOrdering()->evolutionScale(gen->second->lastSplitting(),*(gen->second->splittingKernel()));
if ( isMCatNLOSEvent && !didRadiate && nextScale > ircutoff ) {
if ( eventRecord().incoming().first->coloured() ||
eventRecord().incoming().second->coloured() ) {
assert(theShowerApproximation);
if ( theShowerApproximation->restrictPhasespace() &&
theShowerApproximation->profileScales() ) {
while ( UseRandom::rnd() > theShowerApproximation->hardScaleProfile(hardScale,nextScale) ) {
candidate.continuesEvolving();
Energy nextHardScale = evolutionOrdering()->maxPt(nextScale,candidate,*(gen->second->splittingKernel()));
candidate.hardPt(nextHardScale);
gen->second->generate(candidate,optHardPt,optCutoff);
nextScale = evolutionOrdering()->evolutionScale(gen->second->lastSplitting(),*(gen->second->splittingKernel()));
if ( nextScale <= ircutoff || candidate.stoppedEvolving() )
break;
}
}
}
}
// ATTENTION other profiles go here
if ( nextScale > winnerScale ) {
winner.fill(candidate);
gen->second->completeSplitting(winner);
winnerGen = gen;
winnerScale = nextScale;
}
}
if ( winnerGen == generators().end() ) {
winner.didStopEvolving();
return 0.0*GeV;
}
if ( winner.stoppedEvolving() )
return 0.0*GeV;
return winnerScale;
}
void DipoleShowerHandler::doCascade(unsigned int& emDone,
Energy optHardPt,
Energy optCutoff) {
if ( nEmissions )
if ( emDone == nEmissions )
return;
DipoleSplittingInfo winner;
DipoleSplittingInfo dipoleWinner;
while ( eventRecord().haveChain() ) {
if ( verbosity > 2 ) {
generator()->log() << "DipoleShowerHandler selecting splittings for the chain:\n"
<< eventRecord().currentChain() << flush;
}
list<Dipole>::iterator winnerDip = eventRecord().currentChain().dipoles().end();
Energy winnerScale = 0.0*GeV;
Energy nextLeftScale = 0.0*GeV;
Energy nextRightScale = 0.0*GeV;
for ( list<Dipole>::iterator dip = eventRecord().currentChain().dipoles().begin();
dip != eventRecord().currentChain().dipoles().end(); ++dip ) {
nextLeftScale = getWinner(dipoleWinner,*dip,make_pair(true,false),optHardPt,optCutoff);
if ( nextLeftScale > winnerScale ) {
winnerScale = nextLeftScale;
winner = dipoleWinner;
winnerDip = dip;
}
nextRightScale = getWinner(dipoleWinner,*dip,make_pair(false,true),optHardPt,optCutoff);
if ( nextRightScale > winnerScale ) {
winnerScale = nextRightScale;
winner = dipoleWinner;
winnerDip = dip;
}
if ( evolutionOrdering()->independentDipoles() ) {
Energy dipScale = max(nextLeftScale,nextRightScale);
if ( dip->leftScale() > dipScale )
dip->leftScale(dipScale);
if ( dip->rightScale() > dipScale )
dip->rightScale(dipScale);
}
}
if ( verbosity > 1 ) {
if ( winnerDip != eventRecord().currentChain().dipoles().end() )
generator()->log() << "DipoleShowerHandler selected the splitting:\n"
<< winner << " for the dipole\n"
<< (*winnerDip) << flush;
else
generator()->log() << "DipoleShowerHandler could not select a splitting above the IR cutoff\n"
<< flush;
}
// pop the chain if no dipole did radiate
if ( winnerDip == eventRecord().currentChain().dipoles().end() ) {
eventRecord().popChain();
continue;
}
// otherwise perform the splitting
didRadiate = true;
isMCatNLOSEvent = false;
isMCatNLOHEvent = false;
pair<list<Dipole>::iterator,list<Dipole>::iterator> children;
DipoleChain* firstChain = 0;
DipoleChain* secondChain = 0;
eventRecord().split(winnerDip,winner,children,firstChain,secondChain);
assert(firstChain && secondChain);
evolutionOrdering()->setEvolutionScale(winnerScale,winner,*firstChain,children);
if ( !secondChain->dipoles().empty() )
evolutionOrdering()->setEvolutionScale(winnerScale,winner,*secondChain,children);
if ( verbosity > 1 ) {
generator()->log() << "DipoleShowerHandler did split the last selected dipole into:\n"
<< (*children.first) << (*children.second) << flush;
}
if ( verbosity > 2 ) {
generator()->log() << "After splitting the last selected dipole, "
<< "DipoleShowerHandler encountered the following chains:\n"
<< (*firstChain) << (*secondChain) << flush;
}
if ( theEventReweight ) {
double w = theEventReweight->weight(eventRecord().incoming(),
eventRecord().outgoing(),
eventRecord().hard());
Ptr<StandardEventHandler>::tptr eh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(eventHandler());
assert(eh);
eh->reweight(w);
}
if ( nEmissions )
if ( ++emDone == nEmissions )
return;
}
}
bool DipoleShowerHandler::realign() {
if ( !didRadiate && !intrinsicPtGenerator )
return false;
if ( eventRecord().incoming().first->coloured() ||
eventRecord().incoming().second->coloured() ) {
if ( eventRecord().incoming().first->momentum().perp2()/GeV2 < 1e-10 &&
eventRecord().incoming().second->momentum().perp2()/GeV2 < 1e-10 )
return false;
pair<Lorentz5Momentum,Lorentz5Momentum> inMomenta
(eventRecord().incoming().first->momentum(),
eventRecord().incoming().second->momentum());
SpinOneLorentzRotation transform((inMomenta.first+inMomenta.second).findBoostToCM());
Axis dir = (transform * inMomenta.first).vect().unit();
Axis rot (-dir.y(),dir.x(),0);
double theta = dir.theta();
if ( lastParticles().first->momentum().z() < ZERO )
theta = -theta;
transform.rotate(-theta,rot);
inMomenta.first = transform*inMomenta.first;
inMomenta.second = transform*inMomenta.second;
assert(inMomenta.first.z() > ZERO &&
inMomenta.second.z() < ZERO);
Energy2 sHat =
(eventRecord().incoming().first->momentum() +
eventRecord().incoming().second->momentum()).m2();
pair<Energy,Energy> masses(eventRecord().incoming().first->mass(),
eventRecord().incoming().second->mass());
pair<Energy,Energy> qs;
if ( !eventRecord().incoming().first->coloured() ) {
assert(masses.second == ZERO);
qs.first = eventRecord().incoming().first->momentum().z();
qs.second = (sHat-sqr(masses.first))/(2.*(qs.first+sqrt(sqr(masses.first)+sqr(qs.first))));
} else if ( !eventRecord().incoming().second->coloured() ) {
assert(masses.first == ZERO);
qs.second = eventRecord().incoming().second->momentum().z();
qs.first = (sHat-sqr(masses.second))/(2.*(qs.second+sqrt(sqr(masses.second)+sqr(qs.second))));
} else {
assert(masses.first == ZERO && masses.second == ZERO);
if ( realignmentScheme == 0 ) {
double yX = eventRecord().pX().rapidity();
double yInt = (transform*eventRecord().pX()).rapidity();
double dy = yX-yInt;
qs.first = (sqrt(sHat)/2.)*exp(dy);
qs.second = (sqrt(sHat)/2.)*exp(-dy);
} else if ( realignmentScheme == 1 ) {
Energy sS = sqrt((lastParticles().first->momentum() +
lastParticles().second->momentum()).m2());
qs.first = eventRecord().fractions().first * sS / 2.;
qs.second = eventRecord().fractions().second * sS / 2.;
}
}
double beta =
(qs.first-qs.second) /
( sqrt(sqr(masses.first)+sqr(qs.first)) +
sqrt(sqr(masses.second)+sqr(qs.second)) );
transform.boostZ(beta);
Lorentz5Momentum tmp;
if ( eventRecord().incoming().first->coloured() ) {
tmp = eventRecord().incoming().first->momentum();
tmp = transform * tmp;
eventRecord().incoming().first->set5Momentum(tmp);
}
if ( eventRecord().incoming().second->coloured() ) {
tmp = eventRecord().incoming().second->momentum();
tmp = transform * tmp;
eventRecord().incoming().second->set5Momentum(tmp);
}
eventRecord().transform(transform);
return true;
}
return false;
}
void DipoleShowerHandler::resetAlphaS(Ptr<AlphaSBase>::tptr as) {
for ( vector<Ptr<DipoleSplittingKernel>::ptr>::iterator k = kernels.begin();
k != kernels.end(); ++k ) {
(**k).alphaS(as);
(**k).renormalizationScaleFreeze(theRenormalizationScaleFreeze);
(**k).factorizationScaleFreeze(theFactorizationScaleFreeze);
}
// clear the generators to be rebuild
// actually, there shouldn't be any generators
// when this happens.
generators().clear();
}
void DipoleShowerHandler::resetReweight(Ptr<DipoleSplittingReweight>::tptr rw) {
for ( GeneratorMap::iterator k = generators().begin();
k != generators().end(); ++k )
k->second->splittingReweight(rw);
}
void DipoleShowerHandler::getGenerators(const DipoleIndex& ind,
Ptr<DipoleSplittingReweight>::tptr rw) {
bool gotone = false;
for ( vector<Ptr<DipoleSplittingKernel>::ptr>::iterator k =
kernels.begin(); k != kernels.end(); ++k ) {
if ( (**k).canHandle(ind) ) {
if ( verbosity > 0 ) {
generator()->log() << "DipoleShowerHandler encountered the dipole configuration\n"
<< ind << " in event number "
<< eventHandler()->currentEvent()->number()
<< "\nwhich can be handled by the splitting kernel '"
<< (**k).name() << "'.\n" << flush;
}
gotone = true;
Ptr<DipoleSplittingGenerator>::ptr nGenerator =
new_ptr(DipoleSplittingGenerator());
nGenerator->doCompensate(theDoCompensate);
nGenerator->splittingKernel(*k);
nGenerator->splittingKernel()->renormalizationScaleFactor(renormalizationScaleFactor());
nGenerator->splittingKernel()->factorizationScaleFactor(factorizationScaleFactor());
nGenerator->splittingKernel()->freezeGrid(theFreezeGrid);
GeneratorMap::const_iterator equivalent = generators().end();
for ( GeneratorMap::const_iterator eq = generators().begin();
eq != generators().end(); ++eq ) {
if ( !eq->second->wrapping() )
if ( (**k).canHandleEquivalent(ind,*(eq->second->splittingKernel()),eq->first) ) {
equivalent = eq;
if ( verbosity > 0 ) {
generator()->log() << "The dipole configuration "
<< ind
<< " can equivalently be handled by the existing\n"
<< "generator for configuration "
<< eq->first << " using the kernel '"
<< eq->second->splittingKernel()->name()
<< "'\n" << flush;
}
break;
}
}
if ( equivalent != generators().end() ) {
nGenerator->wrap(equivalent->second);
}
DipoleSplittingInfo dummy;
dummy.index(ind);
nGenerator->splittingReweight(rw);
nGenerator->prepare(dummy);
generators().insert(make_pair(ind,nGenerator));
}
}
if ( !gotone ) {
generator()->logWarning(Exception()
<< "DipoleShowerHandler could not "
<< "find a splitting kernel which is able "
<< "to handle splittings off the dipole "
<< ind << ".\n"
<< "Please check the input files."
<< Exception::warning);
}
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleShowerHandler::doinit() {
ShowerHandler::doinit();
if ( theGlobalAlphaS )
resetAlphaS(theGlobalAlphaS);
}
void DipoleShowerHandler::dofinish() {
ShowerHandler::dofinish();
}
void DipoleShowerHandler::doinitrun() {
ShowerHandler::doinitrun();
}
void DipoleShowerHandler::persistentOutput(PersistentOStream & os) const {
os << kernels << theEvolutionOrdering
<< constituentReshuffler << intrinsicPtGenerator
<< theGlobalAlphaS << chainOrderVetoScales
<< nEmissions << discardNoEmissions << firstMCatNLOEmission << doFSR << doISR
<< realignmentScheme << hardFirstEmission << verbosity << printEvent
<< ounit(theRenormalizationScaleFreeze,GeV)
<< ounit(theFactorizationScaleFreeze,GeV)
<< isMCatNLOSEvent << isMCatNLOHEvent << theShowerApproximation
<< theDoCompensate << maxPtIsMuF << theFreezeGrid
<< theEventReweight;
}
void DipoleShowerHandler::persistentInput(PersistentIStream & is, int) {
is >> kernels >> theEvolutionOrdering
>> constituentReshuffler >> intrinsicPtGenerator
>> theGlobalAlphaS >> chainOrderVetoScales
>> nEmissions >> discardNoEmissions >> firstMCatNLOEmission >> doFSR >> doISR
>> realignmentScheme >> hardFirstEmission >> verbosity >> printEvent
>> iunit(theRenormalizationScaleFreeze,GeV)
>> iunit(theFactorizationScaleFreeze,GeV)
>> isMCatNLOSEvent >> isMCatNLOHEvent >> theShowerApproximation
>> theDoCompensate >> maxPtIsMuF >> theFreezeGrid
>> theEventReweight;
}
ClassDescription<DipoleShowerHandler> DipoleShowerHandler::initDipoleShowerHandler;
// Definition of the static class description member.
void DipoleShowerHandler::Init() {
static ClassDocumentation<DipoleShowerHandler> documentation
("The DipoleShowerHandler class manages the showering using "
"the dipole shower algorithm.",
"The shower evolution was performed using the algorithm described in "
"\\cite{Platzer:2009jq} and \\cite{Platzer:2011bc}.",
"%\\cite{Platzer:2009jq}\n"
"\\bibitem{Platzer:2009jq}\n"
"S.~Platzer and S.~Gieseke,\n"
"``Coherent Parton Showers with Local Recoils,''\n"
" JHEP {\\bf 1101}, 024 (2011)\n"
"arXiv:0909.5593 [hep-ph].\n"
"%%CITATION = ARXIV:0909.5593;%%\n"
"%\\cite{Platzer:2011bc}\n"
"\\bibitem{Platzer:2011bc}\n"
"S.~Platzer and S.~Gieseke,\n"
"``Dipole Showers and Automated NLO Matching in Herwig++,''\n"
"arXiv:1109.6256 [hep-ph].\n"
"%%CITATION = ARXIV:1109.6256;%%");
static RefVector<DipoleShowerHandler,DipoleSplittingKernel> interfaceKernels
("Kernels",
"Set the splitting kernels to be used by the dipole shower.",
&DipoleShowerHandler::kernels, -1, false, false, true, false, false);
static Reference<DipoleShowerHandler,DipoleEvolutionOrdering> interfaceEvolutionOrdering
("EvolutionOrdering",
"Set the evolution ordering to be used.",
&DipoleShowerHandler::theEvolutionOrdering, false, false, true, false, false);
static Reference<DipoleShowerHandler,ConstituentReshuffler> interfaceConstituentReshuffler
("ConstituentReshuffler",
"The object to be used to reshuffle partons to their constitutent mass shells.",
&DipoleShowerHandler::constituentReshuffler, false, false, true, true, false);
static Reference<DipoleShowerHandler,IntrinsicPtGenerator> interfaceIntrinsicPtGenerator
("IntrinsicPtGenerator",
"Set the object in charge to generate intrinsic pt for incoming partons.",
&DipoleShowerHandler::intrinsicPtGenerator, false, false, true, true, false);
static Reference<DipoleShowerHandler,AlphaSBase> interfaceGlobalAlphaS
("GlobalAlphaS",
"Set a global strong coupling for all splitting kernels.",
&DipoleShowerHandler::theGlobalAlphaS, false, false, true, true, false);
static Switch<DipoleShowerHandler,bool> interfaceDoFSR
("DoFSR",
"Switch on or off final state radiation.",
&DipoleShowerHandler::doFSR, true, false, false);
static SwitchOption interfaceDoFSROn
(interfaceDoFSR,
"On",
"Switch on final state radiation.",
true);
static SwitchOption interfaceDoFSROff
(interfaceDoFSR,
"Off",
"Switch off final state radiation.",
false);
static Switch<DipoleShowerHandler,bool> interfaceDoISR
("DoISR",
"Switch on or off initial state radiation.",
&DipoleShowerHandler::doISR, true, false, false);
static SwitchOption interfaceDoISROn
(interfaceDoISR,
"On",
"Switch on initial state radiation.",
true);
static SwitchOption interfaceDoISROff
(interfaceDoISR,
"Off",
"Switch off initial state radiation.",
false);
static Switch<DipoleShowerHandler,bool> interfaceHardFirstEmission
("HardFirstEmission",
"Switch on or off hard first emission.",
&DipoleShowerHandler::hardFirstEmission, false, false, false);
static SwitchOption interfaceHardFirstEmissionOn
(interfaceHardFirstEmission,
"On",
"Switch on hard first emission.",
true);
static SwitchOption interfaceHardFirstEmissionOff
(interfaceHardFirstEmission,
"Off",
"Switch off hard first emission.",
false);
static Switch<DipoleShowerHandler,int> interfaceRealignmentScheme
("RealignmentScheme",
"The realignment scheme to use.",
&DipoleShowerHandler::realignmentScheme, 0, false, false);
static SwitchOption interfaceRealignmentSchemePreserveRapidity
(interfaceRealignmentScheme,
"PreserveRapidity",
"Preserve the rapidity of non-coloured outgoing system.",
0);
static SwitchOption interfaceRealignmentSchemeEvolutionFractions
(interfaceRealignmentScheme,
"EvolutionFractions",
"Use momentum fractions as generated by the evolution.",
1);
static SwitchOption interfaceRealignmentSchemeCollisionFrame
(interfaceRealignmentScheme,
"CollisionFrame",
"Determine realignment from collision frame.",
2);
static Switch<DipoleShowerHandler,bool> interfaceChainOrderVetoScales
("ChainOrderVetoScales",
"[experimental] Switch on or off the chain ordering for veto scales.",
&DipoleShowerHandler::chainOrderVetoScales, true, false, false);
static SwitchOption interfaceChainOrderVetoScalesOn
(interfaceChainOrderVetoScales,
"On",
"Switch on chain ordering for veto scales.",
true);
static SwitchOption interfaceChainOrderVetoScalesOff
(interfaceChainOrderVetoScales,
"Off",
"Switch off chain ordering for veto scales.",
false);
interfaceChainOrderVetoScales.rank(-1);
static Parameter<DipoleShowerHandler,unsigned int> interfaceNEmissions
("NEmissions",
"[debug option] Limit the number of emissions to be generated. Zero does not limit the number of emissions.",
&DipoleShowerHandler::nEmissions, 0, 0, 0,
false, false, Interface::lowerlim);
interfaceNEmissions.rank(-1);
static Switch<DipoleShowerHandler,bool> interfaceDiscardNoEmissions
("DiscardNoEmissions",
"[debug option] Discard events without radiation.",
&DipoleShowerHandler::discardNoEmissions, false, false, false);
static SwitchOption interfaceDiscardNoEmissionsOn
(interfaceDiscardNoEmissions,
"On",
"Discard events without radiation.",
true);
static SwitchOption interfaceDiscardNoEmissionsOff
(interfaceDiscardNoEmissions,
"Off",
"Do not discard events without radiation.",
false);
interfaceDiscardNoEmissions.rank(-1);
static Switch<DipoleShowerHandler,bool> interfaceFirstMCatNLOEmission
("FirstMCatNLOEmission",
"[debug option] Only perform the first MC@NLO emission.",
&DipoleShowerHandler::firstMCatNLOEmission, false, false, false);
static SwitchOption interfaceFirstMCatNLOEmissionOn
(interfaceFirstMCatNLOEmission,
"On",
"",
true);
static SwitchOption interfaceFirstMCatNLOEmissionOff
(interfaceFirstMCatNLOEmission,
"Off",
"",
false);
interfaceFirstMCatNLOEmission.rank(-1);
static Parameter<DipoleShowerHandler,int> interfaceVerbosity
("Verbosity",
"[debug option] Set the level of debug information provided.",
&DipoleShowerHandler::verbosity, 0, 0, 0,
false, false, Interface::lowerlim);
interfaceVerbosity.rank(-1);
static Parameter<DipoleShowerHandler,int> interfacePrintEvent
("PrintEvent",
"[debug option] The number of events for which debugging information should be provided.",
&DipoleShowerHandler::printEvent, 0, 0, 0,
false, false, Interface::lowerlim);
interfacePrintEvent.rank(-1);
static Parameter<DipoleShowerHandler,Energy> interfaceRenormalizationScaleFreeze
("RenormalizationScaleFreeze",
"The freezing scale for the renormalization scale.",
&DipoleShowerHandler::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,Energy> interfaceFactorizationScaleFreeze
("FactorizationScaleFreeze",
"The freezing scale for the factorization scale.",
&DipoleShowerHandler::theFactorizationScaleFreeze, GeV, 2.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Switch<DipoleShowerHandler,bool> interfaceDoCompensate
("DoCompensate",
"",
&DipoleShowerHandler::theDoCompensate, false, false, false);
static SwitchOption interfaceDoCompensateYes
(interfaceDoCompensate,
"Yes",
"",
true);
static SwitchOption interfaceDoCompensateNo
(interfaceDoCompensate,
"No",
"",
false);
static Switch<DipoleShowerHandler,bool> interfaceMaxPtIsMuF
("MaxPtIsMuF",
"",
&DipoleShowerHandler::maxPtIsMuF, false, false, false);
static SwitchOption interfaceMaxPtIsMuFYes
(interfaceMaxPtIsMuF,
"Yes",
"",
true);
static SwitchOption interfaceMaxPtIsMuFNo
(interfaceMaxPtIsMuF,
"No",
"",
false);
static Parameter<DipoleShowerHandler,unsigned long> interfaceFreezeGrid
("FreezeGrid",
"",
&DipoleShowerHandler::theFreezeGrid, 500000, 1, 0,
false, false, Interface::lowerlim);
static Reference<DipoleShowerHandler,DipoleEventReweight> interfaceEventReweight
("EventReweight",
"",
&DipoleShowerHandler::theEventReweight, false, false, true, true, false);
}
diff --git a/DipoleShower/DipoleShowerHandler.h b/DipoleShower/DipoleShowerHandler.h
--- a/DipoleShower/DipoleShowerHandler.h
+++ b/DipoleShower/DipoleShowerHandler.h
@@ -1,491 +1,491 @@
// -*- C++ -*-
//
// DipoleShowerHandler.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_DipoleShowerHandler_H
#define HERWIG_DipoleShowerHandler_H
//
// This is the declaration of the DipoleShowerHandler class.
//
#include "Herwig++/Shower/ShowerHandler.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingInfo.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingReweight.h"
#include "Herwig++/DipoleShower/Kernels/DipoleSplittingKernel.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingGenerator.h"
#include "Herwig++/DipoleShower/Base/DipoleEventRecord.h"
#include "Herwig++/DipoleShower/Base/DipoleEvolutionOrdering.h"
#include "Herwig++/DipoleShower/Base/DipoleEventReweight.h"
#include "Herwig++/DipoleShower/Utility/ConstituentReshuffler.h"
#include "Herwig++/DipoleShower/Utility/IntrinsicPtGenerator.h"
#include "Herwig++/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief The DipoleShowerHandler class manages the showering using
* the dipole shower algorithm.
*
* @see \ref DipoleShowerHandlerInterfaces "The interfaces"
* defined for DipoleShowerHandler.
*/
class DipoleShowerHandler: public ShowerHandler {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
DipoleShowerHandler();
/**
* The destructor.
*/
virtual ~DipoleShowerHandler();
//@}
public:
/**
* Indicate a problem in the shower.
*/
struct RedoShower {};
/**
* Insert an additional splitting kernel.
*/
void addSplitting(Ptr<DipoleSplittingKernel>::ptr sp) {
kernels.push_back(sp);
}
/**
* Reset the alpha_s for all splitting kernels.
*/
void resetAlphaS(Ptr<AlphaSBase>::tptr);
/**
* Reset the splitting reweight for all splitting kernels.
*/
void resetReweight(Ptr<DipoleSplittingReweight>::tptr);
/**
* Return true, if the shower handler can generate a truncated
* shower for POWHEG style events generated using Matchbox
*/
virtual bool canHandleMatchboxTrunc() const { return false; }
protected:
typedef multimap<DipoleIndex,Ptr<DipoleSplittingGenerator>::ptr> GeneratorMap;
/**
* The main method which manages the showering of a subprocess.
*/
virtual tPPair cascade(tSubProPtr sub, XCPtr xcomb) {
return cascade(sub,xcomb,ZERO,ZERO);
}
/**
* The main method which manages the showering of a subprocess.
*/
tPPair cascade(tSubProPtr sub, XCPtr xcomb,
Energy optHardPt, Energy optCutoff);
/**
* Build splitting generators for the given
* dipole index.
*/
void getGenerators(const DipoleIndex&,
Ptr<DipoleSplittingReweight>::tptr rw =
Ptr<DipoleSplittingReweight>::tptr());
/**
* Setup the hard scales.
*/
- void hardScales();
+ void hardScales(Energy2 scale);
/**
* Return the evolution ordering
*/
Ptr<DipoleEvolutionOrdering>::tptr evolutionOrdering() const { return theEvolutionOrdering; }
/**
* Reshuffle to constituent mass shells
*/
void constituentReshuffle();
/**
* Access the generator map
*/
GeneratorMap& generators() { return theGenerators; }
/**
* Access the event record
*/
DipoleEventRecord& eventRecord() { return theEventRecord; }
/**
* Return the event record
*/
const DipoleEventRecord& eventRecord() const { return theEventRecord; }
/**
* Return the splitting kernels.
*/
const vector<Ptr<DipoleSplittingKernel>::ptr>& splittingKernels() const {
return kernels;
}
/**
* Realign the event such as to have the incoming partons along thre
* beam axes.
*/
bool realign();
private:
/**
* Perform the cascade.
*/
void doCascade(unsigned int& emDone,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
/**
* Get the winning splitting for the
* given dipole and configuration.
*/
Energy getWinner(DipoleSplittingInfo& winner,
const Dipole& dip,
pair<bool,bool> conf,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
/**
* Get the winning splitting for the
* given dipole and configuration.
*/
Energy getWinner(SubleadingSplittingInfo& winner,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
/**
* Get the winning splitting for the
* given dipole and configuration.
*/
Energy getWinner(DipoleSplittingInfo& winner,
const DipoleIndex& index,
double emitterX, double spectatorX,
pair<bool,bool> conf,
tPPtr emitter, tPPtr spectator,
Energy startScale,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
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();
/**
* 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:
/**
* The splitting kernels to be used.
*/
vector<Ptr<DipoleSplittingKernel>::ptr> kernels;
/**
* The evolution ordering considered
*/
Ptr<DipoleEvolutionOrdering>::ptr theEvolutionOrdering;
/**
* The ConstituentReshuffler to be used
*/
Ptr<ConstituentReshuffler>::ptr constituentReshuffler;
/**
* The intrinsic pt generator to be used.
*/
Ptr<IntrinsicPtGenerator>::ptr intrinsicPtGenerator;
/**
* A global alpha_s to be used for all splitting kernels.
*/
Ptr<AlphaSBase>::ptr theGlobalAlphaS;
/**
* Apply chain ordering to events from matrix
* element corrections.
*/
bool chainOrderVetoScales;
/**
* Limit the number of emissions.
* Limit applied if > 0.
*/
unsigned int nEmissions;
/**
* Discard events which did not radiate.
*/
bool discardNoEmissions;
/**
* Perform the first MC@NLO emission only.
*/
bool firstMCatNLOEmission;
/**
* Switch on or off final state radiation.
*/
bool doFSR;
/**
* Switch on or off initial state radiation.
*/
bool doISR;
/**
* The realignment scheme
*/
int realignmentScheme;
/**
* True, if first emission should use the available phase space
*/
bool hardFirstEmission;
private:
/**
* The verbosity level.
* 0 - print no info
* 1 - print diagnostic information on setting up
* splitting generators etc.
* 2 - print detailed event information for up to
* printEvent events.
* 3 - print dipole chains after each splitting.
*/
int verbosity;
/**
* See verbosity.
*/
int printEvent;
private:
/**
* The splitting generators indexed by the dipole
* indices they can work on.
*/
GeneratorMap theGenerators;
/**
* The evnt record used.
*/
DipoleEventRecord theEventRecord;
/**
* The number of shoer tries so far.
*/
unsigned int nTries;
/**
* Whether or not we did radiate anything
*/
bool didRadiate;
/**
* Whether or not we did realign the event
*/
bool didRealign;
private:
/**
* A freezing value for the renormalization scale
*/
Energy theRenormalizationScaleFreeze;
/**
* A freezing value for the factorization scale
*/
Energy theFactorizationScaleFreeze;
/**
* True, if we are showering on a MC@NLO S event
*/
bool isMCatNLOSEvent;
/**
* True, if we are showering on a MC@NLO H event
*/
bool isMCatNLOHEvent;
/**
* The matching subtraction, if appropriate
*/
Ptr<ShowerApproximation>::tptr theShowerApproximation;
/**
* True, if sampler should apply compensation
*/
bool theDoCompensate;
/**
* True if maximum pt should be deduced from the factorization scale
*/
bool maxPtIsMuF;
/**
* Return the number of accepted points after which the grid should
* be frozen
*/
unsigned long theFreezeGrid;
/**
* A pointer to the dipole event reweight object
*/
Ptr<DipoleEventReweight>::ptr theEventReweight;
/**
* True if no warnings have been issued yet
*/
static bool firstWarn;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<DipoleShowerHandler> initDipoleShowerHandler;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleShowerHandler & operator=(const DipoleShowerHandler &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of DipoleShowerHandler. */
template <>
struct BaseClassTrait<Herwig::DipoleShowerHandler,1> {
/** Typedef of the first base class of DipoleShowerHandler. */
typedef Herwig::ShowerHandler NthBase;
};
/** This template specialization informs ThePEG about the name of
* the DipoleShowerHandler class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::DipoleShowerHandler>
: public ClassTraitsBase<Herwig::DipoleShowerHandler> {
/** Return a platform-independent class name */
static string className() { return "Herwig::DipoleShowerHandler"; }
/**
* The name of a file containing the dynamic library where the class
* DipoleShowerHandler is implemented. It may also include several, space-separated,
* libraries if the class DipoleShowerHandler 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 "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_DipoleShowerHandler_H */

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 19, 2:35 PM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3804762
Default Alt Text
(72 KB)

Event Timeline