#include "PHASIC++/Channels/Single_Channel.H" #include "PHASIC++/Channels/Multi_Channel.H" #include "ATOOLS/Math/Random.H" #include "ATOOLS/Org/Run_Parameter.H" #include "ATOOLS/Org/MyStrStream.H" #include "ATOOLS/Org/My_MPI.H" #include "ATOOLS/Math/Poincare.H" #include "ATOOLS/Org/My_File.H" #include using namespace PHASIC; using namespace ATOOLS; using namespace std; Multi_Channel::Multi_Channel(string _name) : name(StringReplace(_name, " ", "")), s1(NULL), m_readin(false), m_weight(1.0), n_points(0), n_contrib(0), mn_points(0), mn_contrib(0), m_lastdice(-1), m_otype(0) { } Multi_Channel::~Multi_Channel() { DropAllChannels(); if (s1) { delete[] s1; s1 = NULL; } } void Multi_Channel::Add(Single_Channel * Ch) { channels.push_back(Ch); m_otype = m_otype|Ch->OType(); } size_t Multi_Channel::NChannels() const { size_t nch(0); for (size_t i(0);iNChannels(); return nch; } Single_Channel * Multi_Channel::Channel(int i) { if ((i<0) || (i>=(int)channels.size())) { msg_Error()<<"Multi_Channel::Channel("<(int)channels.size())) { msg_Error()<<"Multi_Channel::DropChannel("<Reset(1./channels.size()); msg_Tracking()<<" "<Name()<<" : "<Alpha()<Size(); if (size>1) { int cn=2*channels.size()+2; double *values = new double[cn]; for (size_t i=0;iMRes1(); values[channels.size()+i]=channels[i]->MRes2(); } values[cn-2]=mn_points; values[cn-1]=mn_contrib; mpi->Allreduce(values,cn,MPI_DOUBLE,MPI_SUM); for (size_t i=0;iSetMPIVars(values[i], values[channels.size()+i]); } mn_points=values[cn-2]; mn_contrib=values[cn-1]; delete [] values; } for (size_t i=0;iCopyMPIValues(); channels[i]->MPISync(); } n_points+=mn_points; n_contrib+=mn_contrib; mn_points=mn_contrib=0.0; #endif } void Multi_Channel::Optimize(double error) { msg_Tracking()<<"Optimize Multi_Channel : "<Res1()/n_points; aptot += channels[i]->Alpha()*sqrt(s1[i]); } // calculate s1x = max_i |aptot - sqrt(s1_i)| // update alpha_i -> alpha_i * sqrt(s1_i) / aptot // = alpha_i * sqrt(W_i(alpha_i)) // where the last expression is given in the notation of hep-ph/9405257 double s1x = 0.; for (i=0;iAlpha()>0.) { if (dabs(aptot-sqrt(s1[i]))>s1x) s1x = dabs(aptot-sqrt(s1[i])); if (channels.size()>1) { channels[i]->SetAlpha(channels[i]->Alpha() * sqrt(s1[i])/aptot); } } } // normalise alpha values to a partition of unity double norm = 0; for (i=0;iAlpha(); for (i=0;iSetAlpha(channels[i]->Alpha() / norm); } // optimise individual channels ... for (i=0;iOptimize(); // save current alpha values if we have improved if (s1xSetAlphaSave(channels[i]->Alpha()); } } // reset channel weights for(i=0;iResetOpt(); msg_Tracking()<<"New weights for : "<Alpha() > 0) { msg_Tracking()<Name()<<" : " <Alpha()<<" -> "<AlphaSave()< "<SetAlpha(channels[i]->AlphaSave()); } // normalise alpha values to a partition of unity double norm = 0; for (i=0;iAlpha(); for (i=0;iSetAlpha(channels[i]->Alpha() / norm); } // tell channels to end optimising for (i=0;iEndOptimize(); msg_Tracking()<<"Best weights:-------------------------------"<Alpha() > 0) { msg_Tracking()<Name() <<" : "<Alpha()<OptimizationFinished()) return false; return true; } void Multi_Channel::AddPoint(double value) { // update number of points #ifdef USING__MPI if (value!=0.) mn_contrib++; mn_points++; #else if (value!=0.) n_contrib++; n_points++; #endif // update weights of all channels double var; for (size_t i=0;iWeight()!=0) { var = sqr(value)*m_weight/channels[i]->Weight(); } else { var = 0.; } #ifdef USING__MPI channels[i]->AddMPIVars(var,sqr(var)); #else channels[i]->SetRes1(channels[i]->Res1() + var); channels[i]->SetRes2(channels[i]->Res2() + sqr(var)); #endif } } // add point to last selected channel if (m_lastdice>=0) Channel(m_lastdice)->AddPoint(value); } void Multi_Channel::GenerateWeight(Vec4D * p,Cut_Data * cuts) { if (channels.empty()) return; Vec4D_Vector pp(p,&p[nin+nout]); m_weight = 0.; if (channels.size()==1) { channels[0]->GenerateWeight(&pp.front(),cuts); if (channels[0]->Weight()!=0) m_weight = channels[0]->Weight(); return; } for (size_t i=0; iAlpha() > 0.) { channels[i]->GenerateWeight(&pp.front(),cuts); if (!(channels[i]->Weight()>0) && !(channels[i]->Weight()<0) && (channels[i]->Weight()!=0)) { msg_Error()<<"Multi_Channel::GenerateWeight(..): ("<name <<"): Channel "<Weight()!=0) m_weight += channels[i]->Alpha()/channels[i]->Weight(); } } if (m_weight!=0) m_weight = 1./m_weight; } void Multi_Channel::GeneratePoint(Vec4D *p,Cut_Data * cuts) { if (m_erans.size()) msg_Debugging()<::iterator it(m_erans.begin());it!=m_erans.end();++it) { it->second=ran->Get(); msg_Debugging()<<" "<first<<" -> "<second<<"\n"; } if (channels.empty()) { if (nin>1) p[2]=p[0]+p[1]; else p[1]=p[0]; return; } Poincare cms(p[0]+p[1]); for(size_t i=0;iSetWeight(0.); if(channels.size()==1) { channels[0]->GeneratePoint(p,cuts); m_lastdice = 0; return; } double rn = ran->Get(); double sum = 0; for (size_t i=0;;++i) { if (i==channels.size()) { rn = ran->Get(); i = 0; sum = 0.; } sum += channels[i]->Alpha(); if (sum>rn) { channels[i]->GeneratePoint(p,cuts); m_lastdice = i; break; } } } void Multi_Channel::GeneratePoint() { if (m_erans.size()) msg_Debugging()<::iterator it(m_erans.begin());it!=m_erans.end();++it) { it->second=ran->Get(); msg_Debugging()<<" "<first<<" -> "<second<<"\n"; } for(size_t i=0;iSetWeight(0.); double disc=ran->Get(); double sum=0.; for (size_t i=0;i<2;++i) rans[i]=ran->Get(); for (size_t n=0;nAlpha(); if (sum>disc) { channels[n]->GeneratePoint(rans); m_lastdice = n; return; } } if (IsEqual(sum,disc)) { channels.back()->GeneratePoint(rans); m_lastdice = channels.size()-1; return; } msg_Error()<<"Multi_Channel::GeneratePoint("<name <<"): Channel "<Name()<<") produces a nan!"<Weight()!=0) m_weight += channels[i]->Alpha()/channels[i]->Weight(); } } if (m_weight!=0) m_weight=1./m_weight; } void Multi_Channel::ISRInfo(int i,int & type,double & mass,double & width) { channels[i]->ISRInfo(type,mass,width); return; } void Multi_Channel::ISRInfo (std::vector &ts,std::vector &ms,std::vector &ws) const { for (size_t i=0;iISRInfo(ts,ms,ws); } void Multi_Channel::Print() { if (!msg_LevelIsTracking()) return; msg_Out()<<"----------------------------------------------"<Name()<<" : "<Alpha()<precision(12); *ofile<Name()<<" "<Alpha()<<" "<AlphaSave()<<" " <<0<<" "<Res1()<<" " <Res2()<WriteOut(pID); } bool Multi_Channel::ReadIn(std::string pID) { My_In_File ifile(pID); if (!ifile.Open()) return false; size_t size; std::string rname; long int points; double alpha, alphasave, weight, res1, res2; *ifile>>size>>rname; if (( size != channels.size()) || ( rname != name) ) { msg_Error()<>n_points>>n_contrib>>s1xmin; double sum=0; for (size_t i=0;i>rname>>points>>alpha>>alphasave>>weight>>res1>>res2; sum+= alpha; if (rname != channels[i]->Name()) { msg_Error()<Name()<Name().substr(0,rname.length()-1)) { msg_Error()<<" return 0."<SetAlpha(alpha); channels[i]->SetAlphaSave(alphasave); channels[i]->SetRes1(res1); channels[i]->SetRes2(res2); } ifile.Close(); for (size_t i=0;iReadIn(pID); return 1; } std::string Multi_Channel::ChID(int n) { return channels[n]->ChID(); } bool Multi_Channel::Initialize() { return true; }