#ifndef EXTAMP_Main_Dipole_Wrapper_Process_H #define EXTAMP_Main_Dipole_Wrapper_Process_H #include "EXTAMP/CS_Dipole.H" #include "EXTAMP/RS_Process.H" #include "PHASIC++/Process/Single_Process.H" namespace EXTAMP { /** A wrapper around a EXTAMP::CS_Dipole that basically adds zero functionality to it, apart from making it look like a PHASIC::Single_Process with a 'Partonic' method that returns the value of the dipole. This is necessary in the MC@NLO implementation due to AMEGIC's legacy structure of representing dipole terms by processes. */ class Dipole_Wrapper_Process : public PHASIC::Single_Process { public: Dipole_Wrapper_Process(const RS_Process& rsproc, EXTAMP::CS_Dipole* dipole, BEAM::Beam_Spectra_Handler* beam, PDF::ISR_Handler* isr); /* Calc dipole kinematics without evaluating dipole. Also perform trigger and set corresponding flag of NLO_subevt */ void CalcKinematics(const ATOOLS::Vec4D_Vector& p); /* After having called CalcKinematics(), evaluate the dipole. */ double Calc(ATOOLS::NLO_subevt* sub); void CalculateScale(const ATOOLS::Vec4D_Vector& real_p, const ATOOLS::Vec4D_Vector& born_p, ATOOLS::NLO_subevt* const evt); /* Inherited from PHASIC::Single_Process. Calls CalcKinematics and Calc, then returns the result. This is used in by Sherpa's MC@NLO implementation for calculating DA and DA-DS */ double Partonic(const ATOOLS::Vec4D_Vector &p, int mode); /* A sign implementing DA and DA-DS as defined in arXiv:1111.1200 */ int MCModeSign(ATOOLS::NLO_subevt* const evt) const; double GetMaxKT2ForDA() const; double GetKT2ofSplitting(const EXTAMP::Dipole_Kinematics& kin) const; bool Combinable(const size_t &idi, const size_t &idj); void FillProcessMap(PHASIC::NLOTypeStringProcessMap_Map *apmap); const ATOOLS::Flavour_Vector &CombinedFlavour(const size_t &idij); /* Set properties of NLO_subevt according to this dipole */ void SetSubEventProperties(ATOOLS::NLO_subevt& sub); /* Set a member pointer to the subevent passed */ void AssignSubEvent(ATOOLS::NLO_subevt* sub); void SetScaleSetter(PHASIC::Scale_Setter_Base* scl) { p_scale = scl; } void SetNLOMC(PDF::NLOMC_Base *const nlomc); /* Set p_scale to NULL in order to avoid deleting it in destructor of PHASIC::Process_Base. It gets deleted in the RS_Process, which owns it. */ ~Dipole_Wrapper_Process() { p_scale = NULL; } private: /* Flavours of this process have to be those of real emission config. NLO_subevts are assigned the born configuration, however. Store corresponding information in these members: */ std::string m_born_name; PHASIC::Process_Info m_born_procinfo; ATOOLS::Flavour_Vector m_born_flavs; const ATOOLS::Flavour_Vector& BornFlavours() const { return m_born_flavs; } static PHASIC::Process_Info ConstructBornProcessInfo(const PHASIC::Process_Info& rsinfo, size_t i, size_t j, const ATOOLS::Flavour& flav_ij) ; /* This pointer (passed in constructor) is assumed to be valid throughout, associated memory is not managed. */ EXTAMP::CS_Dipole* p_dipole; EXTAMP::CS_Dipole* Dipole() const { return p_dipole; } /* RS_Process is supposed to initialize and manages the subevent. */ ATOOLS::NLO_subevt* p_subevent; /* Real emission momentum configuration with momenta of initial state particles reversed. This convention is used in NLO_subevts. */ ATOOLS::Vec4D_Vector m_moms; const ATOOLS::Vec4D_Vector& Momenta() const { return m_moms; } /* Emitter, emitted, spectator index in real emission flavour vector. Follow Sherpa conventions: iI(),Dipole()->J()); } size_t J() const { return std::max(Dipole()->I(),Dipole()->J()); } size_t K() const { return Dipole()->K(); } /* Position of combined flavour ij and spectator k in born configuration */ size_t BornIJ() const { return m_inversemap[Dipole()->BornIJ()]; } size_t BornK() const { return m_inversemap[Dipole()->BornK() ]; } /* Same as in EXTAMP::Process */ double m_norm; const double& NormFac() const { return m_norm; } /* Mapping from ordering in p_dipole to ordering in this class (has to comply with Sherpa ordering conventions): Flavours[i] == Dipole()->Flavours[m_indexmap[i]] Flavours[m_inversemap] == Dipole()->Flavours[i] */ std::vector m_indexmap; std::vector m_inversemap; static std::vector ConstructIndexMapping(const ATOOLS::Flavour_Vector& dipole_flavs, const ATOOLS::Flavour_Vector& process_flavs, size_t nin); static std::vector InvertIndexMapping(const std::vector& map); /* ID vector encoding the id's of particles as they are ordered in the born flavour vector. This is needed for ATOOLS::NLO_Subevents, which own a pointer to such a vector. id's are in binary encoding, meaning the i'th particle has id 1< m_id_vector; const std::vector& IDVector() const {return m_id_vector; } std::vector ConstructIDVector() const; std::map m_cluster_flav_map; }; } #endif