#include "AddOns/Root/Output_RootNtuple.H" #include "ATOOLS/Org/Run_Parameter.H" #include "ATOOLS/Phys/NLO_Subevt.H" #include "PHASIC++/Process/Process_Base.H" #include "ATOOLS/Org/MyStrStream.H" #include "ATOOLS/Org/My_MPI.H" #include "ATOOLS/Org/Scoped_Settings.H" #include "ATOOLS/Org/Message.H" #include "MODEL/Main/Model_Base.H" #include #include #ifdef USING__ROOT #include "TPluginManager.h" #include "TROOT.h" #endif using namespace SHERPA; using namespace ATOOLS; using namespace std; #ifdef USING__MPI MPI_Datatype MPI_rntuple_evt2; MPI_Datatype MPI_Vec4D; #endif Output_RootNtuple::Output_RootNtuple (const Output_Arguments &args,int exact,int ftype): Output_Base("Root"), m_exact(exact), m_ftype(ftype) { Settings& s = Settings::GetMainSettings(); Common_Root_Settings().RegisterDefaults(); RegisterDefaults(); m_mode=s["ROOTNTUPLE_MODE"].Get(); m_treename=s["ROOTNTUPLE_TREENAME"].Get(); m_comp=s["ROOTNTUPLE_COMPRESSION"].Get(); m_basename =args.m_outpath+"/"+args.m_outfile; m_ext = ".root"; m_cnt2=m_cnt3=m_fcnt=m_evt=0; m_idcnt=0; m_avsize=s["ROOTNTUPLE_AVSIZE"].Get(); #ifdef USING__MPI int size=mpi->Size(); if (m_exact) m_avsize=Max((size_t)1,m_avsize/size); #endif m_total=0; m_csumsqr=m_csum=m_cn=0.; m_sum=m_s2=m_s3=m_c1=m_c2=0.; m_sq=m_fsq=m_sq2=m_sq3=0.; #ifdef USING__ROOT p_t3=NULL; p_f=NULL; #ifdef USING__MPI rntuple_evt2 dummye[1]; MPI_Datatype typee[22]={MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE, MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE, MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE, MPI_DOUBLE,MPI_DOUBLE, MPI_LONG,MPI_INT,MPI_INT, MPI_INT,MPI_INT,MPI_INT,MPI_INT, MPI_INT,MPI_DOUBLE,MPI_INT,MPI_CHAR}; int blocklene[22]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,18,1,2}; MPI_Aint basee, dispe[22]; MPI_Get_address(&dummye[0],&basee); MPI_Get_address(&dummye[0].weight,dispe+0); MPI_Get_address(&dummye[0].wgt0,dispe+1); MPI_Get_address(&dummye[0].x1,dispe+2); MPI_Get_address(&dummye[0].x2,dispe+3); MPI_Get_address(&dummye[0].y1,dispe+4); MPI_Get_address(&dummye[0].y2,dispe+5); MPI_Get_address(&dummye[0].fscale,dispe+6); MPI_Get_address(&dummye[0].rscale,dispe+7); MPI_Get_address(&dummye[0].alphas,dispe+8); MPI_Get_address(&dummye[0].kfac,dispe+9); MPI_Get_address(&dummye[0].psw,dispe+10); MPI_Get_address(&dummye[0].id,dispe+11); MPI_Get_address(&dummye[0].ncount,dispe+12); MPI_Get_address(&dummye[0].nparticle,dispe+13); MPI_Get_address(&dummye[0].kf1,dispe+14); MPI_Get_address(&dummye[0].kf2,dispe+15); MPI_Get_address(&dummye[0].f1,dispe+16); MPI_Get_address(&dummye[0].f2,dispe+17); MPI_Get_address(&dummye[0].nuwgt,dispe+18); MPI_Get_address(dummye[0].uwgt,dispe+19); MPI_Get_address(&dummye[0].oqcd,dispe+20); MPI_Get_address(dummye[0].type,dispe+21); for (size_t i=0;i<22;++i) dispe[i]-=basee; MPI_Type_create_struct(22,blocklene,dispe,typee,&MPI_rntuple_evt2); MPI_Type_commit(&MPI_rntuple_evt2); Vec4D dummyv[1]; MPI_Datatype typev[1]={MPI_DOUBLE}; int blocklenv[1]={4}; MPI_Aint basev, dispv[1]; MPI_Get_address(&dummyv[0],&basev); MPI_Get_address(&dummyv[0][0],dispv+0); for (size_t i=0;i<1;++i) dispv[i]-=basev; MPI_Type_create_struct(1,blocklenv,dispv,typev,&MPI_Vec4D); MPI_Type_commit(&MPI_Vec4D); #endif #endif } void Output_RootNtuple::RegisterDefaults() const { Settings& s = Settings::GetMainSettings(); s["ROOTNTUPLE_MODE"].SetDefault(0); s["ROOTNTUPLE_COMPRESSION"].SetDefault(101); s["ROOTNTUPLE_AVSIZE"].SetDefault(10000); } void Output_RootNtuple::Header() { #ifdef USING__ROOT #ifdef USING__MPI int rank=mpi->Rank(); if (rank) return; #endif p_f=new TFile((m_basename+m_ext).c_str(),"recreate"); p_f->SetCompressionSettings(m_comp); p_t3 = new TTree(m_treename.c_str(),"Reconst ntuple"); p_t3->SetMaxTreeSize(2147483647); p_t3->Branch("id",&m_id,"id/I"); if (m_exact) p_t3->Branch("ncount",&m_ncount,"ncount/I"); p_t3->Branch("nparticle",&m_nparticle,"nparticle/I"); if (m_ftype) { p_t3->Branch("px",p_pxd,"px[nparticle]/D"); p_t3->Branch("py",p_pyd,"py[nparticle]/D"); p_t3->Branch("pz",p_pzd,"pz[nparticle]/D"); p_t3->Branch("E",p_Ed,"E[nparticle]/D"); } else { p_t3->Branch("px",p_px,"px[nparticle]/F"); p_t3->Branch("py",p_py,"py[nparticle]/F"); p_t3->Branch("pz",p_pz,"pz[nparticle]/F"); p_t3->Branch("E",p_E,"E[nparticle]/F"); } p_t3->Branch("alphas",&m_alphas,"alphas/D"); if (m_exact) p_t3->Branch("kfactor",&m_kfac,"kfactor/D"); if (m_exact) p_t3->Branch("ps_wgt",&m_psw,"ps_wgt/D"); p_t3->Branch("kf",p_kf,"kf[nparticle]/I"); p_t3->Branch("weight",&m_wgt,"weight/D"); p_t3->Branch("weight2",&m_wgt2,"weight2/D"); p_t3->Branch("me_wgt",&m_mewgt,"me_wgt/D"); p_t3->Branch("me_wgt2",&m_mewgt2,"me_wgt2/D"); p_t3->Branch("x1",&m_x1,"x1/D"); p_t3->Branch("x2",&m_x2,"x2/D"); p_t3->Branch("x1p",&m_y1,"x1p/D"); p_t3->Branch("x2p",&m_y2,"x2p/D"); p_t3->Branch("id1",&m_id1,"id1/I"); p_t3->Branch("id2",&m_id2,"id2/I"); if (m_exact) p_t3->Branch("id1p",&m_id1p,"id1p/I"); if (m_exact) p_t3->Branch("id2p",&m_id2p,"id2p/I"); p_t3->Branch("fac_scale",&m_fscale,"fac_scale/D"); p_t3->Branch("ren_scale",&m_rscale,"ren_scale/D"); p_t3->Branch("nuwgt",&m_nuwgt,"nuwgt/I"); p_t3->Branch("usr_wgts",p_uwgt,"usr_wgts[nuwgt]/D"); p_t3->Branch("alphasPower",&m_oqcd,"alphasPower/B"); p_t3->Branch("part",m_type,"part[2]/C"); ATOOLS::exh->AddTerminatorObject(this); gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo","*", "TStreamerInfo","RIO","TStreamerInfo()"); #endif } Output_RootNtuple::~Output_RootNtuple() { PrepareTerminate(); #ifdef USING__MPI MPI_Type_free(&MPI_rntuple_evt2); MPI_Type_free(&MPI_Vec4D); #endif } void Output_RootNtuple::Footer() { PrepareTerminate(); } void Output_RootNtuple::PrepareTerminate() { StoreEvt(); #ifdef USING__ROOT if (p_t3==NULL) return; p_t3->AutoSave(); delete p_t3; p_t3=NULL; // delete p_f; ATOOLS::exh->RemoveTerminatorObject(this); #endif if (m_exact) { double xs=m_csum/m_cn; double err=sqrt((m_csumsqr/m_cn-sqr(m_csum/m_cn))/(m_cn-1.)); msg_Info()<GetName() <<"' stores "<DecayBlob()) { for (size_t i(0);iDecayBlob()->NOutP();++i) AddDecayProducts(part->DecayBlob()->OutParticle(i),np); return; } DEBUG_VAR("Adding "<<*part); ++np; int kfc=part->Flav().Kfcode(); if (part->Flav().IsAnti()) kfc=-kfc; if (m_fcnt>=m_flavlist.size()) { m_flavlist.resize(m_flavlist.size()+3*m_avsize); m_momlist.resize(m_momlist.size()+3*m_avsize); } m_flavlist[m_fcnt]=kfc; m_momlist[m_fcnt]=part->Momentum(); ++m_fcnt; } void Output_RootNtuple::Output(Blob_List* blobs) { Blob* signal=0, *shower=0; for (Blob_List::const_iterator blit=blobs->begin();blit!=blobs->end();++blit) if ((*blit)->Type()==btp::Signal_Process) { signal=(*blit); } else if ((*blit)->Type()==btp::Shower) { shower=(*blit); } if (!signal || (m_mode==1 && !shower)) return; int ncount=(*signal)["Trials"]->Get(); m_evt+=ncount; m_c1+=ncount; m_cn+=ncount; m_cnt3++; m_idcnt++; Blob *blob=signal; if (m_mode==1) blob=shower; Blob_Data_Base* seinfo=(*signal)["MEWeightInfo"]; ME_Weight_Info* wgtinfo(NULL); if (seinfo) wgtinfo=seinfo->Get(); seinfo=(*signal)["NLO_subeventlist"]; std::string type((*signal)["NLOType"]->Get()); if (!seinfo) { // BVI type events if (m_evtlist.size()<=m_cnt2) m_evtlist.resize(m_evtlist.size()+m_avsize); m_evtlist[m_cnt2].weight = (*signal)["WeightsMap"]->Get().Nominal(); m_evtlist[m_cnt2].ncount=ncount; m_sum+=m_evtlist[m_cnt2].weight; m_csum+=m_evtlist[m_cnt2].weight; m_csumsqr+=sqr(m_evtlist[m_cnt2].weight); m_fsq+=sqr(m_evtlist[m_cnt2].weight); m_evtlist[m_cnt2].id=m_idcnt; m_evtlist[m_cnt2].fscale=sqrt((*signal)["Factorisation_Scale"]->Get()); m_evtlist[m_cnt2].rscale=sqrt((*signal)["Renormalization_Scale"]->Get()); m_evtlist[m_cnt2].alphas=MODEL::s_model->ScalarFunction("alpha_S",m_evtlist[m_cnt2].rscale*m_evtlist[m_cnt2].rscale); m_evtlist[m_cnt2].kfac=wgtinfo->m_K; m_evtlist[m_cnt2].oqcd=(*signal)["Orders"]->Get >()[0]; if (type=="B" || type=="") strcpy(m_evtlist[m_cnt2].type,"B"); else if (type=="V") strcpy(m_evtlist[m_cnt2].type,"V"); else if (type=="I") strcpy(m_evtlist[m_cnt2].type,"I"); else THROW(fatal_error,"Error in NLO type '"+type+"'"); if (wgtinfo) { if (type=="B" || type=="") { m_evtlist[m_cnt2].wgt0=wgtinfo->m_B; m_evtlist[m_cnt2].psw=wgtinfo->m_B/(*signal)["MEWeight"]->Get(); } else if (type=="V" || type=="I") m_evtlist[m_cnt2].wgt0=wgtinfo->m_VI; m_evtlist[m_cnt2].x1=wgtinfo->m_x1; m_evtlist[m_cnt2].x2=wgtinfo->m_x2; m_evtlist[m_cnt2].y1=wgtinfo->m_y1; m_evtlist[m_cnt2].y2=wgtinfo->m_y2; size_t nren(wgtinfo->m_type&mewgttype::VI?wgtinfo->m_wren.size():0), nfac(wgtinfo->m_type&mewgttype::KP?wgtinfo->m_wfac.size():0); m_evtlist[m_cnt2].nuwgt=nren+nfac; if (wgtinfo->m_type&mewgttype::VI) { for (size_t i(0);im_wren[i]; } if (wgtinfo->m_type&mewgttype::KP) { for (size_t i(0);im_wfac[i]; } } for (int i=0;iNInP();i++) { Particle *part=blob->InParticle(i); if (part->ProductionBlob() && part->ProductionBlob()->Type()==btp::Signal_Process) continue; int kfc=part->Flav().Kfcode(); if (part->Flav().IsAnti()) kfc=-kfc; if (part->Momentum()[3]>0.0) m_evtlist[m_cnt2].f1=m_evtlist[m_cnt2].kf1=kfc; else m_evtlist[m_cnt2].f2=m_evtlist[m_cnt2].kf2=kfc; } int np=0; for (int i=0;iNOutP();i++) { Particle *part=blob->OutParticle(i); if (part->DecayBlob()) { if (m_mode==1 && part->DecayBlob()->Type()==btp::Signal_Process) continue; AddDecayProducts(part,np); continue; } ++np; int kfc=part->Flav().Kfcode(); if (part->Flav().IsAnti()) kfc=-kfc; if (m_fcnt>=m_flavlist.size()) { m_flavlist.resize(m_flavlist.size()+3*m_avsize); m_momlist.resize(m_momlist.size()+3*m_avsize); } m_flavlist[m_fcnt]=kfc; m_momlist[m_fcnt]=part->Momentum(); ++m_fcnt; } m_evtlist[m_cnt2].nparticle=np; ++m_cnt2; } else { // RS-type events NLO_subevtlist* nlos = seinfo->Get(); double tweight=0.; for (size_t j=0;jsize();j++) { if ((*nlos)[j]->m_result==0.0) continue; if (m_evtlist.size()<=m_cnt2) m_evtlist.resize(m_evtlist.size()+m_avsize); ATOOLS::Particle_List * pl=(*nlos)[j]->CreateParticleList(); m_evtlist[m_cnt2].weight=(*nlos)[j]->m_result; m_evtlist[m_cnt2].ncount=ncount; tweight+=m_evtlist[m_cnt2].weight; m_evtlist[m_cnt2].nparticle=pl->size(); m_evtlist[m_cnt2].id=m_idcnt; m_evtlist[m_cnt2].wgt0=(*nlos)[j]->m_mewgt; m_evtlist[m_cnt2].fscale=sqrt((*nlos)[j]->m_mu2[stp::fac]); m_evtlist[m_cnt2].rscale=sqrt((*nlos)[j]->m_mu2[stp::ren]); m_evtlist[m_cnt2].alphas=MODEL::s_model->ScalarFunction("alpha_S", m_evtlist[m_cnt2].rscale*m_evtlist[m_cnt2].rscale); m_evtlist[m_cnt2].kfac=(*nlos)[j]->m_K; m_evtlist[m_cnt2].psw=m_evtlist[m_cnt2].weight/(*signal)["MEWeight"]->Get(); m_evtlist[m_cnt2].oqcd=(*signal)["Orders"]->Get >()[0]; if (type!="RS") THROW(fatal_error,"Error in NLO type"); if ((*nlos)[j]->p_real==(*nlos)[j]) strcpy(m_evtlist[m_cnt2].type,"R"); else strcpy(m_evtlist[m_cnt2].type,"S"); if (wgtinfo) { m_evtlist[m_cnt2].x1=wgtinfo->m_x1; m_evtlist[m_cnt2].x2=wgtinfo->m_x2; m_evtlist[m_cnt2].y1=wgtinfo->m_y1; m_evtlist[m_cnt2].y2=wgtinfo->m_y2; } m_evtlist[m_cnt2].nuwgt=0; int swap(signal->InParticle(0)->Momentum()[3]< signal->InParticle(1)->Momentum()[3]); Particle* part=signal->InParticle(swap); int kfc=part->Flav().Kfcode(); if (part->Flav().IsAnti()) kfc=-kfc; m_evtlist[m_cnt2].kf1=kfc; m_evtlist[m_cnt2].f1=(long int)(*nlos)[j]->p_fl[swap]; part=signal->InParticle(1-swap); kfc=part->Flav().Kfcode(); if (part->Flav().IsAnti()) kfc=-kfc; m_evtlist[m_cnt2].kf2=kfc; m_evtlist[m_cnt2].f2=(long int)(*nlos)[j]->p_fl[1-swap]; ++m_cnt2; for (ATOOLS::Particle_List::const_iterator pit=pl->begin(); pit!=pl->end();++pit) { kfc=(*pit)->Flav().Kfcode(); if ((*pit)->Flav().IsAnti()) kfc=-kfc; if (m_fcnt>=m_flavlist.size()) { m_flavlist.resize(m_flavlist.size()+3*m_avsize); m_momlist.resize(m_momlist.size()+3*m_avsize); } m_flavlist[m_fcnt]=kfc; m_momlist[m_fcnt]=(*pit)->Momentum(); ++m_fcnt; delete *pit; } delete pl; } m_sum+=tweight; m_csum+=tweight; m_csumsqr+=sqr(tweight); m_fsq+=sqr(tweight); } if ((rpa->gen.NumberOfGeneratedEvents()%m_avsize)==0) StoreEvt(); } void Output_RootNtuple::ChangeFile() { StoreEvt(); #ifdef USING__ROOT if (p_t3==NULL) return; double xs=m_csum/m_cn; double err=sqrt((m_csumsqr/m_cn-sqr(m_csum/m_cn))/(m_cn-1.)); msg_Info()<GetName() <<"' stores "<ChangeFile(p_f); #endif } void Output_RootNtuple::MPISync() { #ifdef USING__MPI static int s_offset=11; int size=mpi->Size(); if (size>1) { int rank=mpi->Rank(); double vals[6]; if (rank==0) { m_evtlist.resize(m_cnt2); m_flavlist.resize(m_fcnt); m_momlist.resize(m_fcnt); for (int tag=1;tagRecv(&vals,6,MPI_DOUBLE,MPI_ANY_SOURCE,s_offset*size+tag); std::vector evts((int)vals[0]); std::vector flavs((int)vals[3]); std::vector moms((int)vals[3]); mpi->Recv(&evts.front(),(int)vals[0],MPI_rntuple_evt2,MPI_ANY_SOURCE,(s_offset+1)*size+tag); mpi->Recv(&flavs.front(),(int)vals[3],MPI_INT,MPI_ANY_SOURCE,(s_offset+2)*size+tag); mpi->Recv(&moms.front(),(int)vals[3],MPI_Vec4D,MPI_ANY_SOURCE,(s_offset+3)*size+tag); m_evtlist.insert(m_evtlist.end(),evts.begin(),evts.end()); m_flavlist.insert(m_flavlist.end(),flavs.begin(),flavs.end()); m_momlist.insert(m_momlist.end(),moms.begin(),moms.end()); int oid=-1; for (size_t i(m_cnt2);iSend(&vals,6,MPI_DOUBLE,0,s_offset*size+rank); mpi->Send(&m_evtlist.front(),(int)vals[0],MPI_rntuple_evt2,0,(s_offset+1)*size+rank); mpi->Send(&m_flavlist.front(),(int)vals[3],MPI_INT,0,(s_offset+2)*size+rank); mpi->Send(&m_momlist.front(),(int)vals[3],MPI_Vec4D,0,(s_offset+3)*size+rank); m_cnt2=m_cnt3=m_fcnt=m_evt=0; m_sum=m_fsq=0.0; } } #endif } void Output_RootNtuple::StoreEvt() { if (m_cnt2==0) return; MPISync(); #ifdef USING__ROOT if (p_t3==NULL) return; #endif size_t fc=0; double scale2=double(m_cnt2)/double(m_evt); double scale3=double(m_cnt3)/double(m_evt); if (m_exact) scale2=scale3=1.0; for (size_t i=0;iFill(); #endif m_s2+=m_evtlist[i].weight*scale2; m_sq2+=sqr(m_evtlist[i].weight*scale2); m_s3+=m_evtlist[i].weight*scale3; m_c2+=1.; } m_sq+=m_fsq; m_sq3+=m_fsq*sqr(scale3); m_cnt2=m_cnt3=m_fcnt=m_evt=0; m_fsq=0.; } DECLARE_GETTER(Output_RootNtuple,"Root", Output_Base,Output_Arguments); Output_Base *ATOOLS::Getter:: operator()(const Output_Arguments &args) const { return new Output_RootNtuple(args); } void ATOOLS::Getter:: PrintInfo(std::ostream &str,const size_t width) const { str<<"Root NTuple output"; } DECLARE_GETTER(Output_ERootNtuple,"ERoot", Output_Base,Output_Arguments); Output_Base *ATOOLS::Getter:: operator()(const Output_Arguments &args) const { return new Output_RootNtuple(args,1); } void ATOOLS::Getter:: PrintInfo(std::ostream &str,const size_t width) const { str<<"Root NTuple output"; } DECLARE_GETTER(Output_EDRootNtuple,"EDRoot", Output_Base,Output_Arguments); Output_Base *ATOOLS::Getter:: operator()(const Output_Arguments &args) const { return new Output_RootNtuple(args,1,1); } void ATOOLS::Getter:: PrintInfo(std::ostream &str,const size_t width) const { str<<"Root NTuple output"; } void Common_Root_Settings::RegisterDefaults() const { Settings::GetMainSettings()["ROOTNTUPLE_TREENAME"].SetDefault("t3"); }