#include "MEProcess.H" #include "SHERPA/PerturbativePhysics/Matrix_Element_Handler.H" #include "SHERPA/Main/Sherpa.H" #include "SHERPA/Initialization/Initialization_Handler.H" #include "ATOOLS/Math/MathTools.H" #include "ATOOLS/Phys/Cluster_Amplitude.H" #include "ATOOLS/Phys/Flavour.H" #include "ATOOLS/Org/MyStrStream.H" #include "ATOOLS/Org/Run_Parameter.H" #include "ATOOLS/Org/Scoped_Settings.H" #include "PHASIC++/Process/ME_Generator_Base.H" #include "PHASIC++/Process/Process_Base.H" #include "PHASIC++/Process/Process_Info.H" #include "PHASIC++/Process/Subprocess_Info.H" #include "PHASIC++/Channels/Rambo.H" #include "PHASIC++/Main/Process_Integrator.H" #include #include #include MEProcess::MEProcess(SHERPA::Sherpa *a_Generator) : m_nlotype(ATOOLS::nlo_type::lo), p_amp(ATOOLS::Cluster_Amplitude::New()), p_gen(a_Generator), p_proc(NULL), p_rambo(NULL), m_ncolinds(0), m_npsp(0), m_nin(0), m_nout(0), p_colint(NULL) { m_kpz[0]=m_kpz[1]=0.; ATOOLS::Settings::GetMainSettings() .DeclareMatrixSettingsWithEmptyDefault({"MOMENTA"}); } MEProcess::~MEProcess() { if (p_rambo) { delete p_rambo; p_rambo=NULL; } } std::string MEProcess::Name() const { if(!p_proc) THROW(fatal_error, "Process not initialized"); return p_proc->Name(); } void MEProcess::SetMomentumIndices(const std::vector &pdgs) { // fill vector m_mom_inds, such that there is a correspondence // p_ampl->Leg(m_mom_inds[i]) <--> pdgs[i] DEBUG_FUNC(m_nin<<"->"<Leg(j)->Flav().Bar():p_amp->Leg(j)->Flav()); if (thisflav==flav) { msg_Debugging()<< flav <<" <-> "<< thisflav <0) return m_npsp; m_npsp=ATOOLS::Settings::GetMainSettings()["MOMENTA"].GetItemsCount(); return m_npsp; } void MEProcess::ReadProcess(size_t n) { DEBUG_FUNC("n="<()) { msg_Debugging()<(row[1]); } else if (row[0]=="KP_z_1") { msg_Debugging()<<"Set KP-eta values for Beam 1."<(row[1]); } else if (row[0]=="NLOType") { m_nlotype=ATOOLS::ToType(row[1]); } else { int kf(ATOOLS::ToType(row[0])); ATOOLS::Vec4D p(ATOOLS::ToType(row[1]), ATOOLS::ToType(row[2]), ATOOLS::ToType(row[3]), ATOOLS::ToType(row[4])); if (kf!=(long int)p_proc->Flavours()[id]){ std::stringstream err; err << "Momenta must be listed flavour-ordered in run card: " << p_proc->Flavours(); THROW(fatal_error, err.str()); } ATOOLS::ColorID col(0,0); if (row.size()==7) col=ATOOLS::ColorID(ATOOLS::ToType(row[5]), ATOOLS::ToType(row[6])); SetMomentum(id,p); SetColor(id,col); id++; } } msg_Debugging()<<*p_amp<0?id:-id, id>0 ? true : false); p_amp->CreateLeg(ATOOLS::Vec4D(), flav); p_amp->SetNIn(p_amp->NIn()+1); PHASIC::Process_Base::SortFlavours(p_amp); m_inpdgs.push_back(id); m_flavs.push_back(flav); m_nin+=1; } void MEProcess::AddOutFlav(const int &id) { msg_Debugging()<0?id:-id, id>0 ? false : true); p_amp->CreateLeg(ATOOLS::Vec4D(), flav); PHASIC::Process_Base::SortFlavours(p_amp); m_outpdgs.push_back(id); m_flavs.push_back(flav); m_nout+=1; } void MEProcess::AddInFlav(const int &id, const int &col1, const int &col2) { msg_Debugging()<0?id:-id, id>0 ? false : true); p_amp->CreateLeg(ATOOLS::Vec4D(), flav, ATOOLS::ColorID(col1, col2)); p_amp->SetNIn(p_amp->NIn()+1); PHASIC::Process_Base::SortFlavours(p_amp); m_inpdgs.push_back(id); m_flavs.push_back(flav); m_nin+=1; } void MEProcess::AddOutFlav(const int &id, const int &col1, const int &col2) { msg_Debugging()<0?id:-id, id>0 ? false : true); p_amp->CreateLeg(ATOOLS::Vec4D(), flav, ATOOLS::ColorID(col1, col2)); PHASIC::Process_Base::SortFlavours(p_amp); m_outpdgs.push_back(id); m_flavs.push_back(flav); m_nout+=1; } double MEProcess::GenerateColorPoint() { if (p_colint==0) THROW(fatal_error, "No color integrator. Make sure Comix is used."); p_colint->GeneratePoint(); for (size_t i=0; iLegs().size(); ++i) p_amp->Leg(i)->SetCol(ATOOLS::ColorID(p_colint->I()[i],p_colint->J()[i])); SetColors(); return p_colint->GlobalWeight(); } void MEProcess::SetColors() { if (p_colint==0) THROW(fatal_error, "No color integrator. Make sure Comix is used."); PHASIC::Int_Vector ci(p_amp->Legs().size()); PHASIC::Int_Vector cj(p_amp->Legs().size()); for (size_t i=0; iLegs().size(); ++i){ ci[i] = p_amp->Leg(i)->Col().m_i; cj[i] = p_amp->Leg(i)->Col().m_j; } p_colint->SetI(ci); p_colint->SetJ(cj); } void MEProcess::PrintProcesses() const { SHERPA::Matrix_Element_Handler* me_handler = p_gen->GetInitHandler() ->GetMatrixElementHandler(); msg_Info()<<"Available processes:"<ProcMaps().size(); i++) { for (PHASIC::NLOTypeStringProcessMap_Map::const_iterator it=(*me_handler->ProcMaps()[i]).begin(); it!=(*me_handler->ProcMaps()[i]).end();++it) { for (PHASIC::StringProcess_Map::const_iterator sit=it->second->begin();sit!=it->second->end();++sit) { msg_Info()<first<<" : "<second->Name()<GetInitHandler() ->GetMatrixElementHandler(); PHASIC::Process_Vector procs = me_handler->AllProcesses(); if (procs.size()>1) THROW(fatal_error,"More than one process initialised."); return procs[0]; } PHASIC::Process_Base* MEProcess::FindProcess(const ATOOLS::Cluster_Amplitude* amp) { DEBUG_FUNC(""); SHERPA::Matrix_Element_Handler* me_handler(p_gen->GetInitHandler()->GetMatrixElementHandler()); std::string name = PHASIC::Process_Base::GenerateName(amp); msg_Debugging()<<"Looking for "<ProcMaps().size(); i++) { if(me_handler->ProcMaps()[i]->find(m_nlotype)== me_handler->ProcMaps()[i]->end()) continue; PHASIC::StringProcess_Map::const_iterator pit(me_handler->ProcMaps()[i]->find(m_nlotype) ->second->find(name)); if (pit == me_handler->ProcMaps()[i]->find(m_nlotype) ->second->end()) continue; return pit->second; } return NULL; } void MEProcess::Initialize() { DEBUG_FUNC((p_proc?p_proc->Name():"no process set yet")); if (msg_LevelIsDebugging()) PrintProcesses(); // Try to find process by amplitude (assumes it has been filled // through AddInFlav methods etc) p_proc=FindProcess(p_amp); if(!p_proc) { // If not found, assume no flavours have been added and we just want // the first (and only) process initialized through the run card. Check // first if amplitude is really empty to avoid returning a wrong proc. if(p_amp->Legs().size()!=0) THROW(fatal_error, "Requested process not found"); // Retrieve proc initialized through run card and fill amplitude p_proc = FindProcess(); for (size_t i(0);iFlavours().size();++i) { if(iNIn()) AddInFlav((long int)p_proc->Flavours()[i]); else AddOutFlav((long int)p_proc->Flavours()[i]); } } // Check if any of the flavours are 'containters'. // In this case we can't assign any color structure bool container(false); for (size_t i(0);iFlavours().size();++i) if (p_proc->Flavours()[i].Size() > 1) container=true; if(!container) SetUpColorStructure(); std::vector allpdgs; for (std::vector::const_iterator it=m_inpdgs.begin(); it!=m_inpdgs.end(); it++) allpdgs.push_back(*it); for (std::vector::const_iterator it=m_outpdgs.begin(); it!=m_outpdgs.end(); it++) allpdgs.push_back(*it); SetMomentumIndices(allpdgs); p_rambo = new PHASIC::Rambo(m_nin,m_nout, &m_flavs.front(), p_proc->Generator()); } void MEProcess::SetUpColorStructure() { for (unsigned int i = 0; iLegs().size(); i++) { if (p_amp->Leg(i)->Flav().Strong()) { int scharge = p_amp->Leg(i)->Flav().StrongCharge(); if (scharge == 8) m_gluinds.push_back(i); else if (scharge == -3) m_quabarinds.push_back(i); else if (scharge == 3) m_quainds.push_back(i); else { std::stringstream msg; msg << p_amp->Leg(i)->Flav(); THROW(fatal_error, "External leg with unknown strong charge detected: "+msg.str()); } } } m_ncolinds = 2*m_gluinds.size() + m_quabarinds.size() + m_quainds.size(); if (m_ncolinds%2) THROW(fatal_error, "Odd number of color indices"); for (int i(0); i combination; for (int m(0); mIntegrator()->ColorIntegrator()!=NULL) p_colint = p_proc->Integrator()->ColorIntegrator(); } double MEProcess::TestPoint(const double& E){ ATOOLS::Vec4D_Vector p = p_rambo->GeneratePoint(E); SetMomenta(p); if(p_colint!=NULL) GenerateColorPoint(); p_rambo->GenerateWeight(&p[0]); return p_rambo->Weight(); } double MEProcess::MatrixElement() { if(p_colint!=NULL) p_colint->SetWOn(false); double res(p_proc->Differential(*p_amp, ATOOLS::Variations_Mode::nominal_only, 1|4)); if(p_colint!=NULL) p_colint->SetWOn(true); // Cancel out initial state swap factor // which can be accessed through // PHASIC::Process_Base::ISSymFac() res *= p_proc->ISSymFac(); return res; } double MEProcess::CSMatrixElement() { if (p_colint==NULL) return MatrixElement(); GenerateColorPoint(); double r_csme(0.); std::vector >::const_iterator it; std::vector::const_iterator jt; for(it=m_colcombinations.begin(); it!=m_colcombinations.end(); ++it) { int ind(0); int indbar(m_ncolinds/2); for(jt=m_gluinds.begin(); jt!=m_gluinds.end(); ++jt) { p_amp->Leg(*jt)->SetCol(ATOOLS::ColorID((*it)[ind], (*it)[indbar])); ind+=1; indbar+=1; } for(jt=m_quainds.begin(); jt!=m_quainds.end(); ++jt) { p_amp->Leg(*jt)->SetCol(ATOOLS::ColorID((*it)[ind], 0)); ind+=1; } for(jt=m_quabarinds.begin(); jt!=m_quabarinds.end(); ++jt) { p_amp->Leg(*jt)->SetCol(ATOOLS::ColorID(0,(*it)[indbar] )); indbar+=1; } if(ind!=m_ncolinds/2) THROW(fatal_error, "Internal Error"); if(indbar!=m_ncolinds) THROW(fatal_error, "Internal Error"); SetColors(); r_csme+=MatrixElement(); } // Cancel out initial state swap factor // which can be accessed through // PHASIC::Process_Base::ISSymFac() r_csme *= p_proc->ISSymFac(); return r_csme; } double MEProcess::GetFlux() { ATOOLS::Vec4D p0(-p_amp->Leg(0)->Mom()); ATOOLS::Vec4D p1(-p_amp->Leg(1)->Mom()); return 0.25/sqrt(ATOOLS::sqr(p0*p1)-p0.Abs2()*p1.Abs2()); } std::string MEProcess::GeneratorName() { std::string loopgen(""); if (p_proc->Info().m_fi.m_nlotype&ATOOLS::nlo_type::loop) loopgen="+"+p_proc->Info().m_loopgenerator; return p_proc->Generator()->Name()+loopgen; } ATOOLS::Flavour MEProcess::GetFlav(size_t i) { if (i>=m_nin+m_nout) THROW(fatal_error,"Index out of bounds."); ATOOLS::Flavour fl=p_amp->Leg(i)->Flav(); return (i MEProcess::NLOSubContributions() { if (p_proc->IsGroup() && p_proc->Size()>1) THROW(not_implemented, "Not implemented for process groups"); PHASIC::Process_Base* proc = p_proc->IsGroup() ? (*p_proc)[0] : p_proc; std::vector ret; if(proc->GetRSSubevtList()) for(auto& sub : *(proc->GetRSSubevtList())) ret.push_back(sub->m_result); return ret; }