diff --git a/configure.ac b/configure.ac index b00287b..9ac634b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,291 +1,291 @@ -AC_INIT([dyturbo], [1.0.2beta], [stefano.camarda@cern.ch,jakub.cuth@cern.ch]) +AC_INIT([dyturbo], [1.0], [stefano.camarda@cern.ch]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([foreign -Wall -Werror]) #Suppress verbose output when compiling m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) #By default, install binaries in the current directory AC_PREFIX_DEFAULT(${PWD}) AC_PROG_CC m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) #Use libtoolize to build dyturbo libraries AC_PROG_LIBTOOL LT_INIT AC_CONFIG_MACRO_DIR([m4]) # openmp suport AC_ARG_ENABLE([openmp], AC_HELP_STRING(--enable-openmp, [Enable openMP compiler flag -fopenmp. (default=yes)])): ${enable_openmp=yes} AS_IF([test "x$enable_openmp" = "xyes"], [ #AX_OPENMP #[, AC_MSG_ERROR([openmp macro not found])]) #AC_SUBST(OPENMP_CXXFLAGS) #AC_SUBST(OPENMP_LDFLAGS) CXXFLAGS="${CXXFLAGS} -fopenmp" FFLAGS="${FFLAGS} -fopenmp"]) #optimisation flags O3 AC_ARG_ENABLE([O3], AC_HELP_STRING(--enable-O3, [Use compiler optimization flags -O3. (default=yes)])): ${enable_O3=yes} AS_IF([test "x$enable_O3" = "xyes"], [ CXXFLAGS="${CXXFLAGS} -O3" FFLAGS="${FFLAGS} -O3"]) #optimisation flags, O3 or Ofast AC_ARG_ENABLE([Ofast], AC_HELP_STRING(--enable-Ofast, [Use unsafe compiler optimization flags -Ofast. (default=no)])) AS_IF([test "x$enable_Ofast" = "xyes"], [ CXXFLAGS="${CXXFLAGS} -Ofast" FFLAGS="${FFLAGS} -Ofast" ]) #c++11 flag is needed for the random number generator function #CXXFLAGS="${CXXFLAGS} -std=c++11" #older compilers needs c++0x instead CXXFLAGS="${CXXFLAGS} -std=c++0x" #allows usage of complex numbers as x+yi CXXFLAGS="${CXXFLAGS} -fext-numeric-literals" #obsolete fortran do statements #FFLAGS="${FFLAGS} -std=legacy" #allows use of save statements (but causes issues with parallelisation) #FFLAGS="${FFLAGS} -fno-automatic" #use intel compilers #AC_ARG_ENABLE([ifort], # [AC_HELP_STRING(--enable-ifort, [Use ifort2015 and icc2015 compilers. (default=no)])]) #if test x$enable_ifort == xyes #then # AC_PROG_CXX([icc2015]) # AC_PROG_F77([ifort2015]) # AC_PROG_FC([ifort2015]) #else ##use gfortran compilers # AC_PROG_CXX # AC_PROG_F77([gfortran]) # AC_PROG_FC #fi AC_PROG_CXX AC_PROG_F77([gfortran]) AC_PROG_FC # check for lhapdf installation AC_MSG_CHECKING([for lhapdf installation]) # search lhapdf6 in the path lhapdf_config=`which lhapdf-config` if test x$lhapdf_config == x; then # if not found, search lhapdf6 in the lhapdf6 subdirectory lhapdf_config=`ls ${PWD}/lhapdf6/bin/lhapdf-config` if test x$lhapdf_config == x; then # if not found, install it AC_MSG_RESULT([Install LHAPDF6]) ${srcdir}/install-lhapdf #AC_MSG_ERROR([Unable to find lhapdf-config.]) lhapdf_config=`ls ${PWD}/lhapdf6/bin/lhapdf-config` if test x$lhapdf_config == x; then # if the installation fails, exit AC_MSG_ERROR([Failed to install lhapdf.]) fi fi fi # set up lhapdf flags LHAPDF_CPPFLAGS=`${lhapdf_config} --cppflags` LHAPDF_LDFLAGS=`${lhapdf_config} --ldflags` AC_SUBST(LHAPDF_CPPFLAGS) AC_SUBST(LHAPDF_LDFLAGS) AC_MSG_RESULT([Using $lhapdf_config]) # check for Cuba installation, and install it if missing AC_MSG_CHECKING([for Cuba library installation]) AC_SEARCH_LIBS([vegas],[cuba],[ AC_MSG_RESULT([Using -lcuba from system installation]) CUBA_LDFLAGS=-lcuba], [ CUBA_VERSION=4.2 AC_SUBST(CUBA_VERSION) # search for local istallation of Cuba-4.2 cubalib=`ls ${PWD}/Cuba-${CUBA_VERSION}/libcuba.a` if test x$cubalib == x; then # if not found, install it AC_MSG_RESULT([Install Cuba ${CUBA_VERSION}]) ${srcdir}/install-cuba fi cubalib=`ls ${PWD}/Cuba-${CUBA_VERSION}/libcuba.a` if test x$cubalib == x; then AC_MSG_ERROR([Failed to install Cuba ${CUBA_VERSION}.]) fi CUBA_LDFLAGS="-L${PWD}/Cuba-${CUBA_VERSION} -lcuba" CUBA_CPPFLAGS="-I${PWD}/Cuba-${CUBA_VERSION}" AC_MSG_RESULT([Using -lcuba from local installation ${PWD}/Cuba-${CUBA_VERSION}]) ]) ## Use the following to ship cuba as third party library #CUBA_VERSION=4.2 #AC_SUBST(CUBA_VERSION) #AC_CONFIG_SUBDIRS([cuba/Cuba-4.2]) #CUBA_LDFLAGS="-L\$(builddir)/../cuba/Cuba-${CUBA_VERSION} -lcuba" #CUBA_CPPFLAGS="-I\$(srcdir)/../cuba/Cuba-4.2" AC_SUBST(CUBA_CPPFLAGS) AC_SUBST(CUBA_LDFLAGS) ## check for Chaplin installation, and install it if missing #AC_MSG_CHECKING([for chaplin library installation]) #AC_SEARCH_LIBS([hpl2],[hpl3],[ # AC_MSG_RESULT([Using -lchaplin from system installation]) # CHAPLIN_LDFLAGS=-lchaplin], # [ # CHAPLIN_VERSION=1.2 # AC_SUBST(CHAPLIN_VERSION) # # search for local istallation of chaplin-1.2 # chaplinlib=`ls ${PWD}/chaplin-${CHAPLIN_VERSION}/lib/libchaplin.a` # if test x$chaplinlib == x; then # # if not found, install it # AC_MSG_RESULT([Install chaplin ${CHAPLIN_VERSION}]) # ${srcdir}/install-chaplin # fi # chaplinlib=`ls ${PWD}/chaplin-${CHAPLIN_VERSION}/lib/libchaplin.a` # if test x$chaplinlib == x; then # AC_MSG_ERROR([Failed to install chaplin ${CHAPLIN_VERSION}.]) # fi # # CHAPLIN_LDFLAGS="-L${PWD}/chaplin-${CHAPLIN_VERSION}/lib -lchaplin" # AC_MSG_RESULT([Using -lchaplin from local installation ${PWD}/chaplin-${CHAPLIN_VERSION}]) # ]) # #AC_SUBST(CHAPLIN_LDFLAGS) # check for cubature installation, and install it if missing AC_MSG_CHECKING([for cubature source code]) ${srcdir}/install-cubature cubasrc=`ls ${PWD}/cubature/pcubature.c` if test x$cubasrc == x; then AC_MSG_ERROR([Failed to install cubature.]) fi # check for DYRES installation AC_ARG_ENABLE([dyres], AC_HELP_STRING(--enable-dyres, [Install and link original DYRes code, Available only in git (default=no)])) AS_IF([test "x$enable_dyres" = "xyes"], [ AC_MSG_CHECKING([for DYRes installation]) # search in origdyres/DYRes-v1.0 dyresinst=`ls -d ${PWD}/origdyres/DYRes-v1.0` AS_IF([test "x$dyresinst" = x], [ # if not found, install it AC_MSG_RESULT([Install DYRes]) cd ${srcdir}/origdyres && ${srcdir}/install-dyres && cd .. ]) ]) AM_CONDITIONAL([HAVE_DYRES],test "x$enable_dyres" = "xyes") # enable test programs AC_ARG_ENABLE([test], AC_HELP_STRING(--enable-test, [Compile test programs, Available only in git (default=no)])) AS_IF([test "x$enable_test" = "xyes"], [ GMOCK_OFILE="${PWD}/gmock/googlemock/make/gmock_main.a" AC_MSG_CHECKING([for GMock installation]) gmockinst=`ls ${GMOCK_OFILE} 2> /dev/null` AS_IF([test "x$gmockinst" = x], [ # if not found, install it AC_MSG_RESULT([ Gmock not found.. installing]) [ ! test -d ${srcdir}/gmock/googlemock/make ] && git clone https://github.com/google/googletest.git ${srcdir}/gmock; cd ${srcdir}/gmock/googlemock/make && make ; cd -; ]) GMOCK_CPPFLAGS="-pthread -isystem ${PWD}/gmock/googletest/include -isystem ${PWD}/gmock/googlemock/include" GMOCK_LDFLAGS="-lpthread ${GMOCK_OFILE}" AC_MSG_RESULT([ compiling test. Using gmock in ${GMOCK_OFILE}]) ]) AM_CONDITIONAL([HAVE_TEST],test "x$enable_test" = "xyes") AC_SUBST(GMOCK_CPPFLAGS) AC_SUBST(GMOCK_LDFLAGS) # Set --enable-root option, for linking histograms AC_ARG_ENABLE([root], AC_HELP_STRING(--enable-root, [Use root for histograming. (default=no)])) AS_IF([test "x$enable_root" = "xyes"], [ AC_MSG_CHECKING([for root installation]) root_config=`which root-config` AS_IF([test x$root_config == x], [AC_MSG_ERROR([Unable to find root-config.])], [AC_MSG_RESULT([Using $root_config]) root_ok=1 ROOT_CFLAGS=`root-config --cflags` ROOT_LDFLAGS=`root-config --ldflags --libs` AC_SUBST(ROOT_CFLAGS) AC_SUBST(ROOT_LDFLAGS) AC_DEFINE(USEROOT, "1",[ Turn on the ROOT for histogramming.] ) ]) ]) AM_CONDITIONAL([HAVE_ROOT],test "x$enable_root" = "xyes") # Enable debug symbols AC_ARG_ENABLE([debug], [AC_HELP_STRING(--enable-debug, [Add debug flags. (default=no)])]) AS_IF([test "x$enable_debug" = "xyes"], [ AC_MSG_RESULT([Adding debug symbols.]) FFLAGS="$FFLAGS -ggdb -gdwarf" CXXFLAGS="$CXXFLAGS -ggdb -gdwarf" ]) # Check for trapFPE flag AC_ARG_ENABLE([trapFPE], [AC_HELP_STRING(--enable-trapFPE, [Stop of floating point errors (default=no)])]) AS_IF([test "x$enable_trapFPE" = "xyes"], [ AC_MSG_RESULT([Add floating point trap.]) FFLAGS="$FFLAGS -ffpe-trap='invalid,overflow,zero'" ]) # Check for check bounds flag AC_ARG_ENABLE([checkBounds], [AC_HELP_STRING(--enable-checkBounds, [add -fbounds-check flag for compilation (default=no)])]) AS_IF([test "x$enable_checkBounds" = "xyes"], [ AC_MSG_RESULT([Add check bounds flag]) FFLAGS="$FFLAGS -fbounds-check" ]) AC_CONFIG_FILES([Makefile user/Makefile histo/Makefile resum/Makefile counterterm/Makefile vjet/Makefile v2j/Makefile born/Makefile phasespace/Makefile integrands/Makefile dyres/Makefile dynnlo/Makefile mcfm/Makefile cernlib/Makefile dequad/Makefile sandia/Makefile smolpack/Makefile besche/Makefile bessel/Makefile minprescription/Makefile specialfunctions/Makefile ancont/Makefile pegasus/Makefile cubature/Makefile src/Makefile dyturbo-config]) AM_COND_IF([HAVE_DYRES], [ AC_CONFIG_FILES([origdyres/Makefile]) ]) AM_COND_IF([HAVE_TEST], [ AC_CONFIG_FILES([test/Makefile]) ]) #add this to ship cuba # cuba/Makefile AC_OUTPUT diff --git a/counterterm/ctmellin.C b/counterterm/ctmellin.C index 34a7110..6c2544a 100644 --- a/counterterm/ctmellin.C +++ b/counterterm/ctmellin.C @@ -1,259 +1,271 @@ #include "ctmellin.h" #include "qtint.h" #include "mesq.h" #include "anomalous.h" #include "pdfevol.h" #include "parton.h" #include "settings.h" #include "omegaintegr.h" #include "pdf.h" #include "scales.h" #include "phasespace.h" #include "abint.h" #include "resconst.h" #include "dyres_interface.h" #include "switch.h" #include "isnan.h" #include #include #include using namespace std; using namespace anomalous; //Counterterm to be subtracted from V+j to get a finite cross section at qt->0 void ctmellin::calc(double m, double f[]) { for (int npdf = 0; npdf < opts.totpdf; npdf++) f[npdf] = 0.; /////////////////////////////////////////////////////// double m2 = m*m; // double qt2 = qt*qt; // double exppy = exp(y); // double expmy = 1./exppy; //Set scales scales::set(m); scales::mcfm(); double muf = scales::fac; double mur = scales::ren; + //update PDFs in Mellin space at the starting scale, if the factorisation scale is proportional to mll + if (opts.fmufac > 0) + { + pdfevol::allocate(); + pdfevol::update(); + } + pdfevol::allocate_fx(); + /* //Set factorization scale double muf, mur; if (opts.dynamicscale) { //Cannot use dynamic scale, throw an error!!! muf = m*opts.kmufac; mur = m*opts.kmuren; double mur2 = mur*mur; scaleset_(mur2); //set renormalization and factorization scales, and calculate ason2pi and ason4pi } else { muf = opts.rmass*opts.kmufac; mur = opts.rmass*opts.kmuren; } */ //a-parameter of the resummation scale, set it for the dynamic case if (opts.fmures > 0) a_param_.a_param_ = 1./opts.kmures; //for fixed resummation scale need to recompute a_param else a_param_.a_param_ = m/scales::res; ////////////////////////////////////////////////////////// double LR, LF, LQ; if (opts.order >= 2) LR = log(m2/pow(mur,2)); LF = log(m2/pow(muf,2)); LQ = 2.*log(a_param_.a_param_); // skip PDF loop in the preconditioning phase int maxpdf=0; if (dofill_.doFill_ != 0) maxpdf = opts.totpdf; // Start calculation double H1q = 0.; //factors to compensate the as/2/pi normalization (a factor of 2 for each power of alphas) double beta0N = resconst::beta0*2.; double beta1N = resconst::beta1*4.; double beta2N = resconst::beta2*8.; double A1gN = resconst::A1g*2.; double A2gN = resconst::A2g*4.; double A3gN = resconst::A3g*8.; double B1gN = resconst::B1g*2.; double B2gN = resconst::B2g*4.; double A1qN = resconst::A1q*2.; double A2qN = resconst::A2q*4.; double A3qN = resconst::A3q*8.; double B1qN = resconst::B1q*2.; double B2qN = resconst::B2q*4.; double asopi = qcdcouple_.ason2pi_*2.; double bjx = m2/pow(opts.sroot,2); double ax = log(bjx); //double lumi[mesq::totpch]; double sig11[mesq::totpch] = {0.}; double sig12[mesq::totpch] = {0.}; double sig21[mesq::totpch] = {0.}; double sig22[mesq::totpch] = {0.}; double sig23[mesq::totpch] = {0.}; double sig24[mesq::totpch] = {0.}; //Start mellin loop for (int n = 0; n < mellinint::mdim; n++) { //retrieve PDFs in Mellin space at the factorisation scale pdfevol::retrievemuf(n, mesq::positive); complex* fn1 = pdfevol::fn1; complex* fn2 = pdfevol::fn2; int ni = anomalous::index(n,mesq::positive); //Mellin transform complex cexp = exp(-mellinint::Np[n] * ax)/M_PI * mellinint::CCp/complex (0.,1); // cout << mellinint::mdim << " " << n << " " << mellinint::Np[n] << " " << fn1[4] << " " << fn2[4] << endl; //loop on born subprocesses, i.e. born incoming partons ij complex s11,s12,s21,s22,s23,s24; for (int sp = 0; sp < mesq::totpch; sp++) { //simplify notation //double bornmesqij = real(mesq::mesqij[sp]); //born level amplitudes parton::partid i = mesq::pidn1[sp]; //parton 1 parton::partid j = mesq::pidn2[sp]; //parton 2 parton::partid g = parton::g; //gluon parton::partid im = parton::charge_conjn(i); parton::partid jm = parton::charge_conjn(j); //LO term (there is no counterterm at LO...) //Simplest term without convolutions complex tdelta = fn1[i]*fn2[j]; complex th1stF = 2.*gamma1qq[ni]*tdelta + gamma1qg[ni]*(fn1[i]*fn2[g]+fn1[g]*fn2[j]); s12 = -0.5*A1qN*tdelta; s11 = -(B1qN+A1qN*LQ)*tdelta - th1stF; sig11[sp] += real(s11 * cexp * mellinint::wn[n]); sig12[sp] += real(s12 * cexp * mellinint::wn[n]); //sig11[sp] += real(tdelta * cexp * mellinint::wn[n])*real(mesq::mesqij[sp]); //end NLO if (opts.order == 1) continue; complex th1stQ = -(B1qN+A1qN*LQ/2.)*LQ*tdelta; complex th1st = 2.*C1QQ[ni]*tdelta + C1QG[ni]*(fn1[i]*fn2[g]+fn1[g]*fn2[j]); s24 = pow(A1qN,2)/8.*tdelta; s23 = -beta0N*A1qN/3.*tdelta-0.5*A1qN*s11; complex tgaga = +4.*pow(gamma1qq[ni],2)*tdelta +3.*gamma1qq[ni]*gamma1qg[ni]*(fn1[i]*fn2[g]+fn1[g]*fn2[j]) +2.*pow(gamma1qg[ni],2)*(fn1[g]*fn2[g]) +gamma1qg[ni]*gamma1gg[ni]*(fn1[i]*fn2[g]+fn1[g]*fn2[j]); for (int k = 0; k < 2*MAXNF+1; k++) if (k != g) tgaga += gamma1qg[ni]*gamma1gq[ni]*(fn1[i]*fn2[k]+fn1[k]*fn2[j]); s22 = 0.5*(beta0N*A1qN*(LR-LQ)-A2qN)*tdelta -0.5*A1qN*(H1q*tdelta+th1st+th1stQ+(LF-LQ)*th1stF) -0.5*(B1qN+A1qN*LQ-beta0N)*s11 +0.5*(B1qN+A1qN*LQ)*th1stF +0.5*tgaga; // //add this piece to tgaga // for (int k = 0; k < 2*MAXNF+1; k++) // if (k != g) // s22 += 0.5*gamma1qg[ni]*gamma1gq[ni]*(fn1[i]*fn2[k]+fn1[k]*fn2[j]); s21 = -beta0N*(LR-LQ)*s11 -(B1qN+A1qN*LQ)*(H1q*tdelta+th1stQ+th1st+(LF-LQ)*th1stF) -(LF-LQ)*tgaga -(B2qN+A2qN*LQ)*tdelta +beta0N*th1st +(B1qN+A1qN*LQ/2.)*LQ*th1stF - (C1QG[ni]*(gamma1qq[ni]+gamma1gg[ni])+(H1q+2.*C1QQ[ni])*gamma1qg[ni])*(fn1[i]*fn2[g]+fn1[g]*fn2[j]) //tcga -(2.*(gamma2qqV[ni]+gamma2qqS[ni]))*tdelta //tgamma2 -(gamma2qg[ni])*(fn1[i]*fn2[g]+fn1[g]*fn2[j]) -(gamma2qqbV[ni]+gamma2qqbS[ni])*(fn1[i]*fn2[jm]+fn1[im]*fn2[j]) //tgamma2 -2.*C1QG[ni]*gamma1qg[ni]*(fn1[g]*fn2[g]) //tgamma2 -2.*H1q*gamma1qq[ni]*tdelta -4.*C1QQ[ni]*gamma1qq[ni]*tdelta; for (int k = 0; k < 2*MAXNF+1; k++) { if (k != g && k != j && k != jm) s21 -= gamma2qqS[ni]*(fn1[i]*fn2[k]); if (k != g && k != i && k != im) s21 -= gamma2qqS[ni]*(fn1[k]*fn2[j]); } for (int k = 0; k < 2*MAXNF+1; k++) if (k != g) s21 -= C1QG[ni]*gamma1gq[ni]*(fn1[i]*fn2[k]+fn1[k]*fn2[j]); sig21[sp] += real(s21 * cexp * mellinint::wn[n]); sig22[sp] += real(s22 * cexp * mellinint::wn[n]); sig24[sp] += real(s24 * cexp * mellinint::wn[n]); sig23[sp] += real(s23 * cexp * mellinint::wn[n]); } } double xmsq = 0.; for (int sp = 0; sp < mesq::totpch; sp++) { //as/pi factor double sig1 = (sig12[sp]*qtint::LL2_mesqij[sp]+sig11[sp]*qtint::LL1_mesqij[sp])*asopi/2.; xmsq += -sig1; if (opts.order == 1) continue; //(as/pi)^2 factor double sig2 = (sig24[sp]*qtint::LL4_mesqij[sp]+sig23[sp]*qtint::LL3_mesqij[sp]+sig22[sp]*qtint::LL2_mesqij[sp]+sig21[sp]*qtint::LL1_mesqij[sp])*pow(asopi/2.,2); // sum O(as) and O(as^2) contributions xmsq += -sig2; } //Do not fully understand this factor xmsq = xmsq * 3./8. /2./M_PI; //m^2/s factor xmsq = xmsq * m2/pow(opts.sroot,2); //phiV integration xmsq = xmsq * 2*M_PI; if (isnan_ofast(xmsq)) cout << m << " " << xmsq << endl; //switching function is inside qtint, do not apply f[0] = xmsq; //cout << "xmsq " << xmsq << endl; + if (opts.fmufac > 0) + pdfevol::free(); + pdfevol::free_fx(); + return; } diff --git a/input/default.in b/input/default.in index a1537c2..f2ab411 100644 --- a/input/default.in +++ b/input/default.in @@ -1,300 +1,299 @@ -# Output filename -output_filename = results - # Process settings -sroot = 7e3 # center-of-mass energy -ih1 = 1 # hadron 1 -ih2 = 1 # hadron 2 -nproc = 3 # process: 1) W+; 2)W-; 3)Z(/gamma*) -g_param = 1.0 # non perturbative g parameter -order = 2 # order: 0) LO(+LL) 1) NLO(+NLL), 2) NNLO(+NNLL) -fixedorder = false # resummation or fixed order switch - -#Non-perturbative form factors -flavour_kt = false - -#PDF settings +sroot = 7e3 # Center-of-mass energy +ih1 = 1 # Hadron 1: 1 for proton, -1 for antiproton +ih2 = 1 # Hadron 2: 1 for proton, -1 for antiproton +nproc = 3 # Process: 1) W+; 2) W-; 3) Z/gamma* + +# Perturbative order +# fixedorder_only = true # Evaluate predictions at fixed order +# fixedorder_only = false # Evaluate predictions including qt-resummation +fixedorder_only = false +order = 2 # QCD order: 0) LO(+LL), 1) NLO(+NLL), 2) NNLO(+NNLL) + +# Non-perturbative form factor +# Add selector for non perturbative form factor functions +g_param = 1.0 # Non-perturbative g parameter --> rename to g +flavour_kt = false # Flavour-dependent g parameters + +# PDF settings LHAPDFset = CT10nnlo # PDF set from LHAPDF LHAPDFmember = 0 # PDF member -PDFerrors = false # calculate PDF errors - -#QCD scale settings +PDFerrors = false # Calculate PDF errors -#Functional form of QCD scales +# Functional form of QCD scales (mV: wmass or zmass, pT: boson transverse momentum, mjj: dijet invariant mass) #0: mu^2 = mV^2 #1: mu^2 = mll^2 #2: mu^2 = mll^2+pT^2 #3: mu^2 = mll^2+pT^2+mjj^2 - -#---> probably need just one of these options... -fmuren = 0 # Functional form of the renormalisation scale -fmufac = 0 # Functional form of the factorisation scale +fmuren = 1 # Functional form of the renormalisation scale +fmufac = 1 # Functional form of the factorisation scale fmures = 1 # Functional form of the resummation scale (forms 2 and 3 are equivalent to 1) -kmuren = 1. # scale factor for the renormalisation scale -kmufac = 1. # scale factor for the factorisation scale -kmures = 0.5 # scale factor for the resummation scale - -#Additional resummation scales -C1 = 1. -C3 = 1. +# QCD scale settings +kmuren = 0.5 # Scale factor for the renormalisation scale +kmufac = 0.5 # Scale factor for the factorisation scale +kmures = 0.5 # Scale factor for the resummation scale #PDF matching scales -kmuc = 1. # scale factor for the charm matching scale -kmub = 1. # scale factor for the bottom matching scale -kmut = 1. # scale factor for the top matching scale - - -# EW parameters and scheme - -# ewscheme choices: -#0: Input: alpha(mZ), zmass, xw; derived:wmass, Gf -#1: Input: Gf, wmass, zmass; derived: xw, alpha(mZ) [Gmu scheme] -#2: Input: Gf, alpha(mZ), xw, Gf; derived: wmass, zmass +kmuc = 1. # Scale factor for the charm matching scale +kmub = 1. # Scale factor for the bottom matching scale +kmut = 1. # Scale factor for the top matching scale + +# EW scheme +#0: Input: alpha(mZ), zmass, xw; Derived: wmass, Gf +#1: Input: Gf, wmass, zmass; Derived: xw, alpha(mZ) [Gmu scheme] +#2: Input: Gf, alpha(mZ), xw, Gf; Derived: wmass, zmass #3: All masses and couplings determined by inputs ewscheme = 1 -Gf = 1.1663787e-5 # G-Fermi -zmass = 91.1876 # Mass of the Z boson -wmass = 80.385 # Mass of the W boson - -xw = 0.23153 # weak-mixing angle (not used in the Gmu scheme) -aemmz = 7.7585538055706e-03 # alpha_EM(MZ) (not used in the Gmu scheme) +# EW parameters +Gf = 1.1663787e-5 # G-Fermi +zmass = 91.1876 # Mass of the Z boson +wmass = 80.385 # Mass of the W boson +xw = 0.23153 # Weak-mixing angle (not used in the Gmu scheme) +aemmz = 7.7585538055706e-03 # alpha_EM(MZ) (not used in the Gmu scheme) -#W and Z total widths used in the propagators are determined by the following inputs +# W and Z total widths used in the propagator are determined by the following inputs zwidth = 2.4950 # Width of the Z boson wwidth = 2.091 # Width of the W boson -zerowidth = false # zero-width approximation (not really implemented) runningwidth = false # Use Z and W propagators including energy-dependent width effects # CKM matrix Vud = 0.97427 Vus = 0.2253 Vub = 0.00351 Vcd = 0.2252 Vcs = 0.97344 Vcb = 0.0412 # Z/gamma* coupling to quarks Zuu = 1.0 Zdd = 1.0 Zss = 1.0 Zcc = 1.0 Zbb = 1.0 -# include virtual photon in Z/gamma* production +# Include virtual photon and interference in Z/gamma* production useGamma = true - # Resummation parameters -resumcpp = true # use C++ code for resummation -ctcpp = true # use C++ code for the counter term -qtcutoff = 0.02 # resummation cutoff +qtcutoff = 0.02 # Resummation cutoff in GeV -# modlog = true: modified logarithms in the Sudakov L~ = log( (Q*b/b0)^2 + 1) -# modlog = false: canonical logarithms in the Sudakov L = log( (Q*b/b0)^2 ) +# modlog = true # Modified logarithms in the Sudakov L~ = log( (Q*b/b0)^2 + 1) +# modlog = false # Canonical logarithms in the Sudakov L = log( (Q*b/b0)^2 ) modlog = true # Prescription to avoid the Landau pole in the Bessel inverse transform # 0: bstar prescription, which freezes b at bmax: b -> bstar = b/sqrt(1+b^2/bmax^2) # 1: Integrate all the way up to the Landau singularity b_L = b0/Q * exp(1/(2*beta0*alphas)) # 2: Minimal prescription (complex plane) # 3: Minimal prescription (real axis) bprescription = 0 blim = -1 #blim for the bstar prescription, applies to bprescription = 0. A positive value set a fixed bmax=blim, a negative values sets bmax=b_L/(-blim), where b_L is the Landau singularity. phibr = 4. #set arg(z) as phib = pi/phibr for the integration contour in the complex plane for bprescription = 2 (should be set phibr > 4. ) bcf = 0.5 #select the point bc = bcf * b_L, where the integration contour is bended in the complex plane, as a fraction of the Landau singularity b_L. Applies to bprescription = 2 or 3 # Strategy for the direct Mellin transform of PDFs at the factorization scale # Set to 1 to use the dyres approximation of PDFs and integration contour in the complex plane for the Mellin inversion # Set to 0 to use exact PDFs and straight line contour in the complex plane for the Mellin inversion opts_approxpdf = 0 -# number of intervals for integration of PDF moments (direct Mellin transform), relevant only for opts_approxpdf = 0 -opts_pdfintervals = 100 -pdfrule = 200 #Gaussian rule for the x-to-N Mellin transform + +# x-to-N direct Mellin transform of PDFs +opts_pdfintervals = 100 # Number of intervals for integration of PDF moments +pdfrule = 200 # Gaussian rule for the x-to-N Mellin transform # Type of PDF evolution #0: DYRES (backward evolution) #1: Pegasus as DYRES (backward evolution) #2: Mellin transform (forward evolution) #3: Pegasus VFN (forward evolution) #4: Pegasus VFN with alphas from DYRES (forward evolution) evolmode = 0 -# Split the Bessel inverse transform in 3 pieces corresponding to NF=3,4,5 -# and compute a NF-dependent Sudakov form factor -vfnsudakov = false - -#Settings for the Bessel integration -bintaccuracy = 1.0e-4 #accuracy - -#Settings for the inverse Mellin integrations -mellininv = 0 #Strategy for the mellin inverstion (0 Gauss-Legendre, 1 Talbot) -mellinintervals = 1 #number of intervals -mellinrule = 64 #number of nodes - -#options for the Mellin inversion with Gauss-Legendre integration -zmax = 27. #upper limit of the contour in the imaginary axis -cpoint = 1. #point of intersection of the contour with the real axis -phi = 0.5 #angle between the real axis and the linear contour in units of pi - -mellincores = 1 #number of parallel threads for the mellin integration -mellin1d = false #use 1d (y-integrated) or 2d (y-dependent) mellin inversion -xspace = false #access PDFs in Bjorken-x space, without Mellin inversion (option available only in the LL case where the convolution is trivial) - -#number of intervals and gaussian rule for the rapidity integrations in the 2dim resummed piece -yintervals = 1 -yrule = 20 - -#number of intervals and gaussian rule for the qt integration in the 2dim counter term -qtintervals = 1 -qtrule = 64 +# Settings for the inverse Hankel transform +bintaccuracy = 1.0e-4 # Accuracy of the integration -#number of intervals and gaussian rule for the alfa beta scaled-PDF integration in the counter term and born fixed order term -abintervals = 1 -abrule = 64 +# Settings for the inverse Mellin integrations +mellininv = 0 # Strategy for the Mellin inversion (0 Gauss-Legendre, 1 Talbot) +mellinintervals = 1 # Number of intervals +mellinrule = 64 # Number of nodes -#gaussian rule for the phi integration in the V+J 5d LO term when makecuts is false -vjphirule = 20 +# Options for the Mellin inversion with Gauss-Legendre integration +zmax = 27. # Upper limit of the contour in the imaginary axis +cpoint = 1. # Point of intersection of the contour with the real axis +phi = 0.5 # Angle between the real axis and the linear contour in units of pi -#settings for the z1, z2 integration in the V+J 3d NLO term -zrule = 64 +mellincores = 1 # Number of parallel threads for the Mellin integration +mellin1d = false # Use 1d (y-integrated) or 2d (y-dependent) Mellin inversion +xspace = false # Access PDFs in Bjorken-x space, without Mellin inversion (option available only in the LL case where the convolution is trivial) -#settings for the x integration in the V+J 3d delta term -xrule = 200 - -# resummation damping +# Resummation damping damp = true + +# Resummation damping function +# 1: Gaussian: exp(-(k*mll-qt)^2)/(delta*mll)^2 +# 2: Exponential: exp((k*mll)^-qt^2)/(delta*mll)^2 +# 3: Cosine: cos(PI/(delta*mll)*(qt-k*mll))+1)/2 +dampmode = 1 dampk = 0.5 dampdelta = 0.5 -dampmode = 1 - # qt-subtraction cut-off. Both conditions are applied, at least one between qtcut and xqtcut must be > 0 xqtcut = 0.008 # cutoff on qt/m qtcut = 0. # cutoff on qt -# integration settings -rseed = 123456 # random seed for MC integration - -# type of integration for the resummed cross section -intDimRes = 4 # can be 1, 2 or 3 for quadrature, or 4 for vegas +# Integration settings +rseed = 123456 # Random seed for MC integration -# type of integration for the born configuration -intDimBorn = 2 # can be 2 for quadrature, 4 or 6 for vegas - -# type of integration for counter term -intDimCT = 2 # can be 1, 2 or 3 for quadrature, or 6, or 8 for vegas - -# type of integration for V+J finite order -intDimVJ = 3 # can be 3 for quadrature, 5 for quadrature with cuts, or 7 for vegas - -# term switches +# Term switches doBORN = true doCT = true doVJ = true doVJREAL = true doVJVIRT = true +# Integration type: true -> quadrature, false -> vegas +BORNquad = true +CTquad = true +VJquad = true + +# Integration type (advanced settings, override BORNquad, CTquad, VJquad options if set > -1) +intDimRes = -1 # Resummed term (1, 2 or 3 for quadrature, or 4 for vegas) +intDimBorn = -1 # Born term (2 for quadrature, 4 or 6 for vegas) +intDimCT = -1 # Counter term (1, 2 or 3 for quadrature, or 6, or 8 for vegas) +intDimVJ = -1 # V+jet term (3 for quadrature, 5 for quadrature with cuts, or 7 for vegas) + +# Multithreading parallelisation +cores = 0 # Number of parallel threads (0 for turning off parallelisation) + # Cuba settings -cubaverbosity = 0 # Cuba info messsages, from 0 to 3 -cubacores = 0 # parallelization ( 0 = turn off) -cubanbatch = 1000 # the batch size for sampling in Cuba vegas integration -niterBORN = 5 # only for 2d and 3d cuhre integration of resummed part -niterCT = 5 # only for 2d and 3d cuhre integration of counter term -niterVJ = 10 # only for 3d cuhre integration of V+J +cubaverbosity = 0 # Cuba info messsages, from 0 to 3 +cubanbatch = 1000 # The batch size for sampling in Cuba vegas integration +niterBORN = 5 # Only for 2d and 3d cuhre integration of resummed part +niterCT = 5 # Only for 2d and 3d cuhre integration of counter term +niterVJ = 10 # Only for 3d cuhre integration of V+J + +#Vegas settings vegasncallsBORN = 1000 # only for res 4d vegas integration +#vegasncallsRES = 1000 # only for res 4d vegas integration vegasncallsCT = 100000 # only for 6d and 8d vegas integration of the counter term vegasncallsVJLO = 10000000 # only for lo 7d vegas integration vegasncallsVJREAL = 10000000 # only for real 10d vegas integration vegasncallsVJVIRT = 1000000 # only for virt 8d vegas integration vegascollect = false # collect points from all the vegas iterations (true) or only from the last iteration (false) # cubature settings -pcubature = true -relaccuracy = 1e-3 #target relative uncertainty of each term -absaccuracy = 0 #target absolute uncertainty of each term in fb +pcubature = true # Use Cuhre (false ) or pcubature (true) integration in quadrature mode +relaccuracy = 1e-3 # target relative uncertainty of each term +absaccuracy = 0 # target absolute uncertainty of each term in fb + +# Advanced integration settings + +# Number of intervals and gaussian rule for the rapidity integrations in the 2dim resummed piece +yintervals = 1 +yrule = 64 + +# Number of intervals and gaussian rule for the qt integration in the 2dim counter term +qtintervals = 1 +qtrule = 64 + +# Number of intervals and gaussian rule for the alfa beta scaled-PDF integration in the counter term and born fixed order term +abintervals = 1 +abrule = 64 + +# Gaussian rule for the phi integration in the V+J 5d LO term when makecuts is false +vjphirule = 20 + +# Settings for the z1, z2 integration in the V+J 3d NLO term +zrule = 64 + +# Settings for the x integration in the V+J 3d delta term +xrule = 200 # costh CS boundaries costhmin = -1 costhmax = +1 # Lepton cuts # Total cross section or with lepton cuts makecuts = false # charged leptons cuts lptcut = 20 -lycut = 2.5 +lycut = 2.5 # absolute rapidity cut +lycutmin # leptons and antileptons cuts lepptcut = 0 lepycut = 1000 alpptcut = 0 alpycut = 1000 #absolute-rapidity-ordered leptons (central and forward) lcptcut = 0 lcymin = 0 lcymax = 1000 lfptcut = 0 lfymin = 0 lfymax = 1000 # cuts on neutrino and transverse mass etmisscut = 0 mtcut = 0 #costh CS cthCSmin = -1 cthCSmax = +1 # integration types and settings for costh phi_lep phase space cubaint = false # integration with Cuba Suave trapezint = false # trapezoidal rule for the phi_lep integration and semi-analytical for costh quadint = true # quadrature rule for the phi_lep integration and semi-analytical for costh suavepoints = 1000000 # number of points for suave integration, newpoints is set to suavepoints/10; nphitrape = 1000 # number of steps for trapezoidal rule of phi_lep integration phirule = 4 # quadrature rule of phi_lep integration phiintervals = 20 # number of segments for quadrature rule of phi_lep integration ncstart = 100 # starting sampling for the costh semi-analytical integration (common settings for the trapezoidal and quadrature rules) # qt-recoil prescriptions qtrec_naive = false qtrec_cs = true qtrec_kt0 = false -# debug settings +# Debug settings timeprofile = false # debug and time profile resummation integration verbose = false # debug and time profile costh phi_lep integration -gridverbose = false # printout events to keep job alive when running on grid -texttable = true # dump result table to text file (including pdf variations) -unicode = false # use unicode characters for the table formatting + +# Output settings +output_filename = results # output filename +texttable = true # dump result table to text file (including pdf variations) +redirect = false # redirect stdout and stderr to log file (except for gridverbose output) +unicode = false # use unicode characters for the table formatting +silent = false # no output on screen (except for gridverbose output) +makehistos = true # fill histograms +gridverbose = false # printout number of events to keep job alive when running on grid + +# Compute total (-1) or helicity cross sections (0-7) +helicity = -1 # binning # normalise cross sections by bin width ptbinwidth = false ybinwidth = false +mbinwidth = false # Force to loop over all bins even you have all Vegas integrands force_binsampling = false -# Compute total (-1) or helicity cross sections (0-7) -helicity = -1 - -# pt, y, m bins +# qt, y, m bins qt_bins = [ 0 2 4 6 8 10 12 14 16 18 22 26 30 34 38 42 46 50 54 60 70 80 100 150 200 300 800 ] -y_bins = [ -5. 0. 5. ] -m_bins = [ 50 66. 116. 1000. ] +y_bins = [ -5 5 ] +m_bins = [ 66 116 ] # binning for user testing histogram biganswer_bins = [ 41 42 43 ] - -# # z angular -# qt_bins = [ 0 2.5 5.0 8.0 11.4 14.9 18.5 22.0 25.5 29.0 32.6 36.4 40.4 44.9 50.2 56.4 63.9 73.4 85.4 105.0 132.0 173.0 253.0 600.0 ] -# y_bins = [ -5 5 ] diff --git a/mcfm/mcfm_interface.C b/mcfm/mcfm_interface.C index 650a36f..64d8517 100644 --- a/mcfm/mcfm_interface.C +++ b/mcfm/mcfm_interface.C @@ -1,212 +1,212 @@ #include "mcfm_interface.h" #include "settings.h" #include "coupling.h" #include "resconst.h" #include "phasespace.h" #include #include #include map plabel; void mcfm::init() { energy_.sroot_ = opts.sroot; density_.ih1_ = opts.ih1; density_.ih2_ = opts.ih2; nproc_.nproc_ = opts.nproc; - zerowidth_.zerowidth_ = opts.zerowidth; - // dynamicscale_.dynamicscale_ = opts.dynamicscale; // Dynamic scale (if true mufac=muren=q) + zerowidth_.zerowidth_ = false; //Could drop everywhere from the mcfm code + //dynamicscale_.dynamicscale_ = opts.dynamicscale; //not used anymore, should drop // CKM matrix entries cabib_.Vud_ = opts.Vud; cabib_.Vus_ = opts.Vus; cabib_.Vub_ = opts.Vub; cabib_.Vcd_ = opts.Vcd; cabib_.Vcs_ = opts.Vcs; cabib_.Vcb_ = opts.Vcb; dymasses_.wwidth_ = opts.wwidth; dymasses_.zwidth_ = opts.zwidth; //initialise MCFM settings noglue_.noglue_=false; noglue_.ggonly_=false; noglue_.gqonly_=false; string part = "tota"; strncpy(part_.part_ , part.c_str(), part.size()); colc_.colourchoice_=0; cutoff_.cutoff_=0.001; //add to settings (this is a cut off in mcfm on invariant mass pairs between emitted and radiator) flags_.qflag_=true; flags_.gflag_=true; //Catani-Seymour subtraction cut-offs for initial-initial, initial-final, final-initial, and final-final dipoles //(add to settings) alfacut_.aii_=1.;//0.01; alfacut_.aif_=1.;//0.01; alfacut_.afi_=1.;//0.01; alfacut_.aff_=1.;//0.01; //Limits on invariant mass of vector boson decay products //(irrelevant if zerowidth=true) limits_.wsqmin_=pow(phasespace::mmin,2); limits_.wsqmax_=pow(phasespace::mmax,2); //Check if the limits are compatible with sroot if (limits_.wsqmax_> pow(energy_.sroot_,2)) limits_.wsqmax_=pow(energy_.sroot_,2); plabel[1]="pp"; plabel[2]="pp"; //dycoupling_(); coupling::init(); dymasses_.mb_=0; //probably irrelevant to set the bottom mass to 0, since it is not used anywhere if (!((density_.ih1_==1) && (density_.ih2_ == -1)) && !((density_.ih1_==1) && (density_.ih2_ == 1))) { cout << "The selected initial state is not valid," << endl; cout << "please select proton-proton (1 1) or proton-antiproton (1 -1)" << endl; exit(0); } //the default behaviour is to remove no branching ratio bool removebr=false; brnrat_.brnrat_=1.; //branching ratios double brwen,brzee,brtau,brtop; branch_(brwen,brzee,brtau,brtop); //W+->l+nubar if (nproc_.nproc_ == 1) { plabel[3]="nl"; plabel[4]="ea"; plabel[5]="pp"; plabel[6]="pp"; nwz_.nwz_=1; breit_.mass3_= dymasses_.wmass_; breit_.width3_= dymasses_.wwidth_; opts.rmass = dymasses_.wmass_; opts.rwidth = dymasses_.wwidth_; if (removebr) brnrat_.brnrat_=brwen; } //W-=>l-nu else if(nproc_.nproc_ == 2) { plabel[3]="el"; plabel[4]="na"; plabel[5]="pp"; plabel[6]="pp"; nwz_.nwz_=-1; breit_.mass3_=dymasses_.wmass_; breit_.width3_=dymasses_.wwidth_; opts.rmass = dymasses_.wmass_; opts.rwidth = dymasses_.wwidth_; if (removebr) brnrat_.brnrat_=brwen; } else if(nproc_.nproc_==3) { plabel[3]="el"; plabel[4]="ea"; plabel[5]="pp"; plabel[6]="pp"; nwz_.nwz_=0; breit_.mass3_=dymasses_.zmass_; breit_.width3_=dymasses_.zwidth_; opts.rmass = dymasses_.zmass_; opts.rwidth = dymasses_.zwidth_; zcouple_.l1_=zcouple_.le_; zcouple_.r1_=zcouple_.re_; //with q1=0 the photon contribution is switched off //with q1=-1 the photon contribution is switched on dyphoton_.phot_=zcouple_.q1_; if (removebr) brnrat_.brnrat_=brzee; } else { cout << "Wrong process" << endl; exit(0); } //Breit Wigner unweighting settings //the jets, particles 5 and 6, are not resonant breit_.n2_=0; breit_.mass2_=0; breit_.width2_=0; //the leptons, particles 3 and 4, are resonant breit_.n3_=1; //Decide if worth using Breit-Wigner unweighting or not for the dilepon system //n3=0 //vmass=wmass //if(nproc.eq.3) vmass=zmass //if(mwmin.lt.vmass.and.mwmax.gt.vmass) n3=1 ckmfill_(nwz_.nwz_); // Set-up PS integration cut-offs //double rtsmin = 40; //rtsmin = min (rtsmin, sqrt(limits_.wsqmin_ + cutoff_.cutoff_)); double rtsmin = max (sqrt(limits_.wsqmin_), cutoff_.cutoff_); if (zerowidth_.zerowidth_) { rtsmin = dymasses_.wmass_; if (nproc_.nproc_ == 3) rtsmin = dymasses_.zmass_; } taumin_.taumin_=pow((rtsmin/energy_.sroot_),2); taumin_.logtaumin_=log(taumin_.taumin_); xmin_.xmin_=taumin_.taumin_; //Set-up incoming beams (used only in realint.f) pext_.p1ext_[3]=-0.5*energy_.sroot_; pext_.p1ext_[0]=0.; pext_.p1ext_[1]=0.; pext_.p1ext_[2]=-0.5*energy_.sroot_; pext_.p2ext_[3]=-0.5*energy_.sroot_; pext_.p2ext_[0]=0.; pext_.p2ext_[1]=0.; pext_.p2ext_[2]=+0.5*energy_.sroot_; //set NF to 5 (it is used in H2calc) nf_.nf_ = resconst::NF; } void mcfm::set_mass_bounds() { //Reset limits on invariant mass of vector boson decay products limits_.wsqmin_=pow(phasespace::mmin,2); limits_.wsqmax_=pow(phasespace::mmax,2); //update all variables that depends on the mass boundaries double rtsmin = max (sqrt(limits_.wsqmin_), cutoff_.cutoff_); if (zerowidth_.zerowidth_) { rtsmin = dymasses_.wmass_; if (nproc_.nproc_ == 3) rtsmin = dymasses_.zmass_; } taumin_.taumin_=pow((rtsmin/energy_.sroot_),2); taumin_.logtaumin_=log(taumin_.taumin_); xmin_.xmin_=taumin_.taumin_; } diff --git a/resum/anomalous.C b/resum/anomalous.C index 4797ea0..53a9cb8 100644 --- a/resum/anomalous.C +++ b/resum/anomalous.C @@ -1,231 +1,286 @@ #include "anomalous.h" #include "mesq.h" #include "interface.h" #include "resconst.h" #include complex *anomalous::ans; complex *anomalous::am; complex *anomalous::ap; complex *anomalous::al; complex *anomalous::be; complex *anomalous::ab; complex *anomalous::rmin; complex *anomalous::rplus; complex *anomalous::rqq; complex *anomalous::rqg; complex *anomalous::rgq; complex *anomalous::rgg; complex *anomalous::RMMQQ; complex *anomalous::RMMQG; complex *anomalous::RMMGQ; complex *anomalous::RMMGG; complex *anomalous::RMPQQ; complex *anomalous::RMPQG; complex *anomalous::RMPGQ; complex *anomalous::RMPGG; complex *anomalous::RPMQQ; complex *anomalous::RPMQG; complex *anomalous::RPMGQ; complex *anomalous::RPMGG; complex *anomalous::RPPQQ; complex *anomalous::RPPQG; complex *anomalous::RPPGQ; complex *anomalous::RPPGG; complex *anomalous::C1QQ; complex *anomalous::C1QG; complex *anomalous::C1GQ; complex anomalous::C1GG; complex *anomalous::gamma1qq; complex *anomalous::gamma1qg; complex *anomalous::gamma1gq; complex *anomalous::gamma1gg; complex *anomalous::gamma2qq; complex *anomalous::gamma2qqV; complex *anomalous::gamma2qqbV; complex *anomalous::gamma2qqS; complex *anomalous::gamma2qqbS; complex *anomalous::gamma2qg; complex *anomalous::gamma2gq; complex *anomalous::gamma2gg; complex *anomalous::C2qgM; complex *anomalous::C2NSqqM; complex *anomalous::C2SqqbM; complex *anomalous::C2NSqqbM; void anomalous::init() { // ANOMALOUS DIMENSIONS FOR LEADING AND NEXT TO LEADING ORDER // EVOLUTION OF PARTON DENSITIES AND WILSON COEFFICIENTS FOR // NLO STRUCTURE FUNCTIONS : // all values are precalculated at the values of the z points used for the complex contour of the Mellin inverse transform //settings: nf = 5 (flavours) int nf = resconst::NF; ans = new complex [mellinint::mdim*2]; am = new complex [mellinint::mdim*2]; ap = new complex [mellinint::mdim*2]; al = new complex [mellinint::mdim*2]; be = new complex [mellinint::mdim*2]; ab = new complex [mellinint::mdim*2]; rmin = new complex [mellinint::mdim*2]; rplus = new complex [mellinint::mdim*2]; rqq = new complex [mellinint::mdim*2]; rqg = new complex [mellinint::mdim*2]; rgq = new complex [mellinint::mdim*2]; rgg = new complex [mellinint::mdim*2]; RMMQQ = new complex [mellinint::mdim*2]; RMMQG = new complex [mellinint::mdim*2]; RMMGQ = new complex [mellinint::mdim*2]; RMMGG = new complex [mellinint::mdim*2]; RMPQQ = new complex [mellinint::mdim*2]; RMPQG = new complex [mellinint::mdim*2]; RMPGQ = new complex [mellinint::mdim*2]; RMPGG = new complex [mellinint::mdim*2]; RPMQQ = new complex [mellinint::mdim*2]; RPMQG = new complex [mellinint::mdim*2]; RPMGQ = new complex [mellinint::mdim*2]; RPMGG = new complex [mellinint::mdim*2]; RPPQQ = new complex [mellinint::mdim*2]; RPPQG = new complex [mellinint::mdim*2]; RPPGQ = new complex [mellinint::mdim*2]; RPPGG = new complex [mellinint::mdim*2]; C1QQ = new complex [mellinint::mdim*2]; C1QG = new complex [mellinint::mdim*2]; C1GQ = new complex [mellinint::mdim*2]; gamma1qq = new complex [mellinint::mdim*2]; gamma1qg = new complex [mellinint::mdim*2]; gamma1gq = new complex [mellinint::mdim*2]; gamma1gg = new complex [mellinint::mdim*2]; gamma2qq = new complex [mellinint::mdim*2]; gamma2qqV = new complex [mellinint::mdim*2]; gamma2qqbV = new complex [mellinint::mdim*2]; gamma2qqS = new complex [mellinint::mdim*2]; gamma2qqbS = new complex [mellinint::mdim*2]; gamma2qg = new complex [mellinint::mdim*2]; gamma2gq = new complex [mellinint::mdim*2]; gamma2gg = new complex [mellinint::mdim*2]; C2qgM = new complex [mellinint::mdim*2]; C2NSqqM = new complex [mellinint::mdim*2]; C2SqqbM = new complex [mellinint::mdim*2]; C2NSqqbM = new complex [mellinint::mdim*2]; for (int sign = mesq::positive; sign <= mesq::negative; sign++) for (int i = 0; i < mellinint::mdim; i++) { fcomplex fxn; //input of ancalc complex cxn; if (sign == mesq::positive) { fxn.real = real(mellinint::Np[i]); fxn.imag = imag(mellinint::Np[i]); cxn = mellinint::Np[i]; } else { fxn.real = real(mellinint::Nm[i]); fxn.imag = imag(mellinint::Nm[i]); cxn = mellinint::Nm[i]; } fcomplex QQI, QGF, GQI, GGI, GGF, NS1MI, NS1PI, NS1F, QQ1F, QG1F, GQ1I, GQ1F, GG1I, GG1F; //input: fxn //output: QQI, QGF, GQI, GGI, GGF, NS1MI, NS1PI, NS1F, QQ1F, QG1F, GQ1I, GQ1F, GG1I, GG1F; ancalc_(QQI, QGF, GQI, GGI, GGF, NS1MI, NS1PI, NS1F, QQ1F, QG1F, GQ1I, GQ1F, GG1I, GG1F, fxn); fcomplex ANS, AM, AP, AL, BE, AB, RMIN, RPLUS, RQQ, RQG, RGQ, RGG, C2Q, C2G, CDYQ, CDYG; //output of anom fcomplex CDYQI;// = 0.; //unused dummy input fcomplex CDYGI;// = 0.; //unused dummy input fcomplex C2QI;// = 0.; //unused dummy input --> check fcomplex C2GF;// = 0.; //unused dummy input --> check //inputs: QQI, QGF, GQI, GGI, GGF, NS1MI, NS1PI, NS1F, QQ1F, QG1F, GQ1I, GQ1F, GG1I, GG1F, C2QI, C2GF, CDYQI, CDYGI (only function of fxn and nf) //outputs ans, am, ap, al, be, ab, rmin, rplus, rqq, rgg, rgq, rgg (are also only function of fxn) anom_(ANS, AM, AP, AL, BE, AB, RMIN, RPLUS, RQQ, RQG,RGQ, RGG, C2Q, C2G, CDYQ, CDYG, fxn, nf, QQI, QGF, GQI, GGI, GGF, NS1MI, NS1PI, NS1F, QQ1F, QG1F, GQ1I, GQ1F, GG1I, GG1F, C2QI, C2GF, CDYQI, CDYGI); ans[index(i,sign)] = cx(ANS); am[index(i,sign)] = cx(AM); ap[index(i,sign)] = cx(AP); al[index(i,sign)] = cx(AL); be[index(i,sign)] = cx(BE); ab[index(i,sign)] = cx(AB); rmin[index(i,sign)] = cx(RMIN); rplus[index(i,sign)] = cx(RPLUS); rqq[index(i,sign)] = cx(RQQ); rqg[index(i,sign)] = cx(RQG); rgq[index(i,sign)] = cx(RGQ); rgg[index(i,sign)] = cx(RGG); // Compute R coefficients complex AC = 1.- cx(AL); complex NMP = 1.- cx(AM) + cx(AP); complex NPM = 1.- cx(AP) + cx(AM); complex DMQQ = cx(AL) * cx(RQQ) + cx(BE) * cx(RGQ); complex DMQG = cx(AL) * cx(RQG) + cx(BE) * cx(RGG); complex DMGQ = cx(AB) * cx(RQQ) + AC * cx(RGQ); complex DMGG = cx(AB) * cx(RQG) + AC * cx(RGG); complex DPQQ = AC * cx(RQQ) - cx(BE) * cx(RGQ); complex DPQG = AC * cx(RQG) - cx(BE) * cx(RGG); complex DPGQ = -cx(AB) * cx(RQQ) + cx(AL) * cx(RGQ); complex DPGG = -cx(AB) * cx(RQG) + cx(AL) * cx(RGG); RMMQQ[index(i,sign)]= cx(AL) * DMQQ+cx(AB)*DMQG; RMMQG[index(i,sign)]= cx(BE) * DMQQ+ AC *DMQG; RMMGQ[index(i,sign)]= cx(AL) * DMGQ+cx(AB)*DMGG; RMMGG[index(i,sign)]= cx(BE) * DMGQ+ AC *DMGG; RMPQQ[index(i,sign)]= ( AC * DMQQ-cx(AB)*DMQG)/NMP; RMPQG[index(i,sign)]=(-cx(BE) * DMQQ+cx(AL)*DMQG)/NMP; RMPGQ[index(i,sign)]= ( AC * DMGQ-cx(AB)*DMGG)/NMP; RMPGG[index(i,sign)]=(-cx(BE) * DMGQ+cx(AL)*DMGG)/NMP; RPMQQ[index(i,sign)]= (cx(AL) * DPQQ+cx(AB)*DPQG)/NPM; RPMQG[index(i,sign)]= (cx(BE) * DPQQ+ AC *DPQG)/NPM; RPMGQ[index(i,sign)]= (cx(AL) * DPGQ+cx(AB)*DPGG)/NPM; RPMGG[index(i,sign)]= (cx(BE) * DPGQ+ AC *DPGG)/NPM; RPPQQ[index(i,sign)]= AC * DPQQ-cx(AB)*DPQG; RPPQG[index(i,sign)]= -cx(BE) * DPQQ+cx(AL)*DPQG; RPPGQ[index(i,sign)]= AC * DPGQ-cx(AB)*DPGG; RPPGG[index(i,sign)]= -cx(BE) * DPGQ+cx(AL)*DPGG; // C1 coefficients double pi2 = M_PI*M_PI; C1QG[index(i,sign)]=1./((cxn+1.)*(cxn+2.)); C1GQ[index(i,sign)]=4./3./(cxn+1.); C1QQ[index(i,sign)]=2.*pi2/3.-16./3.+4./3./(cxn*(cxn+1.)); // = 2. * resconst::C1qqn + 4./3./(cxn*(cxn+1.)); C1GG=pi2/2.+11./2.+pi2; // = 2. * resconst::C1ggn; // gamma1 gamma2: NORMALIZED ANOMALOUS DIMENSIONS AND COEFFICIENTS gamma1qq[index(i,sign)]=-1.*(cx(QQI)/4.); gamma1qg[index(i,sign)]=-1.*(cx(QGF)/8.); gamma1gq[index(i,sign)]=-1.*(cx(GQI)/4.); gamma1gg[index(i,sign)]=-1.*((cx(GGI)+(double)nf*cx(GGF))/4.); gamma2qq[index(i,sign)]=-1.*(((cx(NS1PI)+(double)nf*cx(NS1F))+(double)nf*cx(QQ1F))/8.); gamma2qqV[index(i,sign)]=-1.*(cx(NS1PI)+2*(double)nf*cx(NS1F)+cx(NS1MI))/16.; gamma2qqbV[index(i,sign)]=-1.*(cx(NS1PI)-cx(NS1MI))/16.; gamma2qqS[index(i,sign)]=-1.*(cx(QQ1F)/16.); gamma2qqbS[index(i,sign)]=gamma2qqS[index(i,sign)]; gamma2qg[index(i,sign)]=-1.*(cx(QG1F)/16.); gamma2gq[index(i,sign)]=-1.*((cx(GQ1I)+(double)nf*cx(GQ1F))/8.); gamma2gg[index(i,sign)]=-1.*((cx(GG1I)+(double)nf*cx(GG1F))/8.); // C2 coefficients //input: fxn and nf from the common block fcomplex C2qg,C2NSqqb,C2NSqq,C2Sqqb; h2calc_(C2qg,C2NSqqb,C2NSqq,C2Sqqb,fxn); C2qgM[index(i,sign)] = cx(C2qg); C2NSqqM[index(i,sign)] = cx(C2NSqq); C2SqqbM[index(i,sign)] = cx(C2Sqqb); C2NSqqbM[index(i,sign)] = cx(C2NSqqb); } } + +void anomalous::release() +{ + delete[] ans; + delete[] am; + delete[] ap; + delete[] al; + delete[] be; + delete[] ab; + delete[] rmin; + delete[] rplus; + delete[] rqq; + delete[] rqg; + delete[] rgq; + delete[] rgg; + + delete[] RMMQQ; + delete[] RMMQG; + delete[] RMMGQ; + delete[] RMMGG; + delete[] RMPQQ; + delete[] RMPQG; + delete[] RMPGQ; + delete[] RMPGG; + delete[] RPMQQ; + delete[] RPMQG; + delete[] RPMGQ; + delete[] RPMGG; + delete[] RPPQQ; + delete[] RPPQG; + delete[] RPPGQ; + delete[] RPPGG; + + delete[] C1QQ; + delete[] C1QG; + delete[] C1GQ; + + delete[] gamma1qq; + delete[] gamma1qg; + delete[] gamma1gq; + delete[] gamma1gg; + delete[] gamma2qq; + delete[] gamma2qqV; + delete[] gamma2qqbV; + delete[] gamma2qqS; + delete[] gamma2qqbS; + delete[] gamma2qg; + delete[] gamma2gq; + delete[] gamma2gg; + + delete[] C2qgM; + delete[] C2NSqqM; + delete[] C2SqqbM; + delete[] C2NSqqbM; +} diff --git a/resum/anomalous.h b/resum/anomalous.h index 07c8ff9..2ffba55 100644 --- a/resum/anomalous.h +++ b/resum/anomalous.h @@ -1,22 +1,23 @@ #ifndef anomalous_h #define anomalous_h #include "mellinint.h" namespace anomalous { extern void init(); + extern void release(); extern complex *ans,*am,*ap,*al,*be,*ab; extern complex *rmin,*rplus,*rqq,*rqg,*rgq,*rgg; extern complex *RMMQQ,*RMMQG,*RMMGQ,*RMMGG,*RMPQQ,*RMPQG,*RMPGQ,*RMPGG,*RPMQQ,*RPMQG,*RPMGQ,*RPMGG,*RPPQQ,*RPPQG,*RPPGQ,*RPPGG; extern complex *C1QQ,*C1QG,*C1GQ; extern complex C1GG; extern complex *gamma1qq,*gamma1qg,*gamma1gq,*gamma1gg; extern complex *gamma2qq,*gamma2qqV,*gamma2qqbV,*gamma2qqS,*gamma2qqbS,*gamma2qg,*gamma2gq,*gamma2gg; extern complex *C2qgM,*C2NSqqM,*C2SqqbM,*C2NSqqbM; inline int index(int i, int sign) {return i + sign*mellinint::mdim;} } #endif diff --git a/resum/besselint.C b/resum/besselint.C index e123631..c77cf3c 100644 --- a/resum/besselint.C +++ b/resum/besselint.C @@ -1,430 +1,433 @@ #include "resconst.h" #include "settings.h" #include "besselint.h" #include "pdfevol.h" #include "pegasus.h" #include "mesq.h" #include "hcoefficients.h" #include "hcoeff.h" #include "phasespace.h" #include "gaussrules.h" #include "resint.h" #include "isnan.h" #include "pdf.h" #include "sudakovff.h" #include "npff.h" #include +double C1 = 1; +double C3 = 1; + //fortran interface void besselint_(double &b, double &qt, double &q2) { resint::_qt = qt; resint::_m = sqrt(q2); besselint::bint(b); }; complex besselint::bint(complex b) { if (b == 0.) return 1.; //Should be correct, since J_0(0) = 1, and S(0) = 1 (Sudakov). May be different in the case that the L~ = L+1 matching is not used. complex bb = b; double qt = resint::_qt; //better take this from phasespace::qt //pdfevol::bscale is used for //alpq (C1) //pdfevol::alpr (C3) //pdfevol::XL (C3) //aexp (C1) //it also used in evolmode 1 and 4 as factorisation scale //The soft scale of the resummation is b0/b. The factor a = mll/mures is introduced because the b scale is used in alphasl //Introduce two scales: //mub = C1*b0/b is the lower integration limit of the Sudakov integral - complex mub = resint::a * resconst::b0/b * opts.C1; + complex mub = resint::a * resconst::b0/b * C1; //pdfevol::bscale = C3*b0/b is the "soft" factorisation scale at which the Wilson coefficient functions are evaluated (see arxiv:1309.1393 for details) - pdfevol::bscale = resint::a * resconst::b0/b * opts.C3; + pdfevol::bscale = resint::a * resconst::b0/b * C3; //convert to fortran complex number fcomplex fscale2_mub = fcx(pow(mub,2)); fcomplex fscale2_mufb = fcx(pow(pdfevol::bscale,2)); //freeze PDF evolution below a certain scale // if (pdfevol::bscale < 5.) // pdfevol::bscale = 5.; //pdfevol::bstarscale and pdfevol::bstartilde are not used (be careful, they do no have the C3 scale) //bstarscale = a*b0/bstar (final scale used for the PDF evolution) double bstar = real(b / sqrt(1.+(b*b)/(blimit_.rblim_*blimit_.rblim_))); pdfevol::bstarscale = resconst::b0*resint::a/bstar; //qbstar is used in evolmode 3 //qbstar = b0/bstar, it corresponds to pdfevol::bsstarcale but without a_param - pdfevol::qbstar = resconst::b0/bstar*opts.C3; + pdfevol::qbstar = resconst::b0/bstar*C3; //simulate pythia ISR factorisation scale, which is muf^2 = qt^2 (i.e. avoid the bstar prescription to freeze the factorisation scale) - //pdfevol::qbstar = resconst::b0/b*opts.C3; + //pdfevol::qbstar = resconst::b0/b*C3; //bstartilde is bstarscale (qbstar) with the modification L -> L~, which freezes the scale at muf //bstartilde is used in evolmode 2, for the direct mellin transfrom at each scale //pdfevol::bstartilde = pdfevol::bstarscale * resint::mufac / sqrt((pow(pdfevol::bstarscale,2) + resint::mufac2)); if (opts.modlog) pdfevol::bstartilde = pdfevol::qbstar * resint::mures / sqrt((pow(pdfevol::qbstar,2) + resint::mures2)); else pdfevol::bstartilde = pdfevol::qbstar; //complex PDF scale to be used for the minimal prescription pdfevol::bcomplex = resconst::b0/b; // cout << b << " " << bstar << " " << blimit_.rblim_ << endl; //The integration from b to qt space is done with the bstar prescription (real axis in the b space), and use the bessel function //The (complex) integration in the minimal prescription would require hankel functions //******************** //qt and b dependence (bessel function) (is xj0 a jacobian? Probably yes, the Jacobian for the change of variable from cartesian to radial coordinate, which translates from Fourier to Hankel transform) double xj0; double qtb = qt*real(b); if (resint::_mode == 3) //qt-integrated mode --> Needs to be implemented also for the other prescriptions xj0 = 2.*fort_besj1_(qtb)/real(b); else { //bstar prescription if (opts.bprescription == 0) xj0 = 2.*fort_besj0_(qtb); //xj0 = 2.*fort_besj1_(qtb)/real(b); //--> this line is to check the qt-integral as a function of qt used in mode 3 //Integrate up to blim with besche else if (opts.bprescription == 1) xj0 = 2.; //Minimal prescription else if (opts.bprescription == 2 || opts.bprescription == 3) xj0 = 2.; } //******************** //The Sudakov is mass and b dependent //fortran fcomplex fbb = fcx(bb); complex sudak=cx(s_(fbb)); //C++ //complex sudak=sudakov::sff(bb); if (sudak == 0.) return 0.; //non-perturbative form factor //sudak *= exp(-opts.g_param*pow(b,2)); complex ff = npff::S(b,resint::_m,resint::x1,resint::x2); if (!opts.flavour_kt) sudak *= ff; //******************** //b, qt and mass dependence complex factorfin = bb*xj0*sudak; //******************** //Do not need the Mellin transform for the LL case, because the HN coefficient is 1 --> Use PDFs in x space if (opts.order == 0 && opts.xspace && (opts.evolmode == 0 || opts.evolmode == 1)) return real(factorfin); //************************************** //b-dependence // Set scales for evolution in pdfevol //alphasl gives the LL/NLL evolution of alpha from Qres=Q/a_param to q2=b0^2/b^2 /********************************************/ //pdfevol::alpqf is used as starting scale of the PDF evolution in pdfevol::evolution //according to Eq. 42 of arXiv:hep-ph/0508068 it should be the factorisation scale, //but in Eq. 98 in the resummation scale is used double alpqf = resint::alpqres; //alphas at resummation scale (as in dyres) //double alpqf = resint::alpqfac; //alphas at factorisation scale (as in Eq. 42 of arXiv:hep-ph/0508068, but see also Eq. 98) /********************************************/ /********************************************/ //alpq is used in hcoefficients::calcb, it is alpq = alphas(b0^2/b^2) //it is used only at NLL, at NNLL instead aexp and aexpb are used (aexp is the same as alphasl, but with a different blim) complex alpq; alpq = resint::alpqres * cx(alphasl_(fscale2_mub)); //--> Attention! in DYRES it is alphas(qres), in DyQT it is alphas(mur) if (opts.evolmode == 2 || opts.evolmode == 3) //In order to have variable flavour evolution, use here a VFN definition of alpq //There is possibly an issue here when the renormalisation scale is (very) different from mll, since aass=alphas(muren) is used in xlambda = beta0*aass*blog { // double M2 = pow(fabs(pdfevol::bstartilde),2); double M2 = pow(fabs(pdfevol::qbstar),2); //qbstar = b0/bstar (without a_param) double M2tilde; if (opts.modlog) M2tilde = M2 * resint::mures2 / (M2 + resint::mures2); //modified logs L -> L~ else M2tilde = M2; double M2prime = M2tilde * resint::muren2/resint::mures2; //scale for differences between muren and mures M2 = M2prime; double R2 = M2; double ASI; int NF; alpq = pegasus::alphas(M2, R2, ASI, NF); //alpq = LHAPDF::alphasPDF(sqrt(M2)) / (4.* M_PI); /* //tweak this to look as in dyres, where alphas(muren) is used: double R20 = resint::_m; alpq = as_(M2, R20, resint::alpqren, NF); alpq = alpq/resint::alpqren*resint::alpqres; */ //Based on the definition of aexp, may be need to rescale alpq for as(qres)/as(muren)? //alpq = alpq/resint::alpqren*resint::alpqres; //cout << "alpq " << alpq << " M2 " << M2 << endl; } // complex alpq = LHAPDF::alphasPDF(fabs(pdfevol::bstartilde))/4./M_PI; //alpq = alphas(b0^2/b^2) // cout << pdfevol::bstarscale << " " << resint::alpqres * cx(alphasl_(fscale2)) << " " << LHAPDF::alphasPDF(fabs(pdfevol::bstartilde))/4./M_PI << endl; /********************************************/ //pdfevol::XL = pdfevol::alpqf / alpq; // = 1./cx(alphasl_(fscale2)); pdfevol::XL = 1./cx(alphasl_(fscale2_mufb)); //XL = alphas(mures2)/alphas(b0^2/b^2) pdfevol::XL1 = 1.- pdfevol::XL; pdfevol::SALP = log(pdfevol::XL); //cout << pdfevol::bscale << " " << pdfevol::XL << endl; // SELECT ORDER FOR EVOLUTION LO/NLO pdfevol::alpr = alpqf * cx(alphasl_(fscale2_mufb))*(double)(opts.order-1); //force LO evolution //pdfevol::alpr = alpqf * cx(alphasl_(fscale2_mufb))*(double)(0); //cout << b << " " << scale2 << " " << pdfevol::SALP << " " << log(1./cx(alphasl_(fscale2))) << " " << pdfevol::alpr << " " << alpq << endl; //************************************** //************************************** //Perform PDF evolution //original dyres evolution: Perform PDF evolution from muf to the scale b0/b ~ pt //the scales used in the evolution correspond to SALP and alpr if (opts.evolmode == 0) for (int i = 0; i < mellinint::mdim; i++) pdfevol::evolution (i); //PDF evolution with Pegasus QCD from muf to the scale b0/b ~ pt else if (opts.evolmode == 1) pegasus::evolve(); //Calculate PDF moments by direct Mellin transformation at each value of bstarscale = b0p/bstar //else if (opts.evolmode == 2) //for (int i = 0; i < mellinint::mdim; i++) //pdfevol::calculate(i); else if (opts.evolmode == 2) pdfevol::calculate(); //PDF evolution with Pegasus QCD from the starting scale Q20, in VFN else if (opts.evolmode == 3) pegasus::evolve(); //PDF evolution with Pegasus QCD from the starting scale Q20, in VFN, and using alphasl(nq2) to evaluate ASF at the final scale else if (opts.evolmode == 4) pegasus::evolve(); //Truncate moments from xmin to 1, with xmin = m/sqrt(s) e^-y0 (currently works only at LL where the HN coefficient is 1) //if (opts.mellin1d) // pdfevol::truncate(); //pdfevol::uppertruncate(); // for (int i = 0; i < mellinint::mdim; i++) // cout << "C++ " << b << " " << i << " " << cx(creno_.cfx1_[i][5]) << endl; //************************************** //aexp and aexpb are calculated in alphasl, they are used in hcoefficients::calcb only for the NNLL cross section alphasl_(fscale2_mub); complex aexp = cx(exponent_.aexp_); //aexp is actually the ratio alphas(a*b0/b)/alphas(muren) //calculate aexp = alphas(a*b0/b)/alphas(muren) using LHAPDF //aexp = LHAPDF::alphasPDF(real(pdfevol::bstartilde))/LHAPDF::alphasPDF(resint::muren); // //In order to have variable flavour evolution, use here a VFN definition of aexp (aexpB instead, should be independent from NF) // //It seems that the pt-integrated cross section is invariant for variations of a_param if aexp is the ratio of alpq/as(muren) (and not alpq/as(Qres)) // //Indeed, aexp is always multiplied by aass, which is alphas at the renormalisation scale // if (opts.evolmode == 2 || opts.evolmode == 3) //account for VFN evolution // aexp = alpq / resint::alpqren; // //aexp = alpq / resint::alpqres; //cout << pdfevol::bstartilde << " " << cx(exponent_.aexp_) << " " << alpq / resint::alpqres << " " << alpq / resint::alpqren << endl; complex aexpb = cx(exponent_.aexpb_); //In case of truncation of hcoeff, need to recalculate the original coefficients before truncation //if (opts.mellin1d) //hcoeff::calc(resint::aass,resint::logmuf2q2,resint::logq2muf2,resint::logq2mur2,resint::loga); // Cache the positive and negative branch of coefficients which depend only on one I index if (opts.mellin1d) hcoeff::calcb(resint::aass,resint::logmuf2q2,resint::loga,alpq,aexp,aexpb); // --> Need to access aass,logmuf2q2,loga,alpq,aexp,aexpb else hcoefficients::calcb(resint::aass,resint::logmuf2q2,resint::loga,alpq,aexp,aexpb); // --> Need to access aass,logmuf2q2,loga,alpq,aexp,aexpb //Inverting the HN coefficients from N to z space does not work, because it would miss the convolution with PDFs //double q2 = pow(phasespace::m,2); //if (opts.mellin1d) //hcoeff::invert(q2); //Truncate HN coefficients, to implement mellin1d also for rapdity intervals (currently not working, not sure if it is eventually possible. Need to figure out how to truncate the moments) //if (opts.mellin1d) //hcoeff::truncate(); //Apply flavour dependent non-perturbative form factors if (opts.flavour_kt) pdfevol::flavour_kt(); complex invres = 0.; double fun = 0.; //Do not need the Mellin transform for the LL case, because the HN coefficient is 1 --> Use PDFs in x space if (opts.order == 0 && opts.xspace && (opts.evolmode == 2 || opts.evolmode == 3 || opts.evolmode == 4)) { double muf; //double muf = fabs(pdfevol::bstartilde); //double muf = resconst::b0/b; // if (opts.evolmode == 2) // muf = fabs(pdfevol::qbstar); // if (opts.evolmode == 4) // muf = fabs(pdfevol::qbstar); //muf = fabs(pdfevol::bscale); muf = fabs(pdfevol::bstartilde); // //PDFs // double fx1[2*MAXNF+1],fx2[2*MAXNF+1]; // fdist_(opts.ih1,resint::x1,muf,fx1); // fdist_(opts.ih2,resint::x2,muf,fx2); // // //mesq::setmesq_expy(1, resint::_m, resint::_costh, resint::_y); // for (int sp = 0; sp < mesq::totpch; sp++) // fun += fx1[mesq::pid1[sp]]*fx2[mesq::pid2[sp]]*real(mesq::mesqij[sp]); if (resint::_mode < 2) //rapidity differential { //PDFs double fx1[2*MAXNF+1],fx2[2*MAXNF+1]; fdist_(opts.ih1,resint::x1,muf,fx1); fdist_(opts.ih2,resint::x2,muf,fx2); for (int sp = 0; sp < mesq::totpch; sp++) fun += fx1[mesq::pid1[sp]]*fx2[mesq::pid2[sp]]*real(mesq::mesqij[sp]); } else //rapidity integration { for (int i=0; i < opts.yintervals; i++) { double ya = phasespace::ymin+(phasespace::ymax-phasespace::ymin)*i/opts.yintervals; double yb = phasespace::ymin+(phasespace::ymax-phasespace::ymin)*(i+1)/opts.yintervals; double xc = 0.5*(ya+yb); double xm = 0.5*(yb-ya); for (int j=0; j < opts.yrule; j++) { double y = xc+xm*gr::xxx[opts.yrule-1][j]; double exppy = exp(y); double expmy = 1./exppy; double x1 = resint::tau*exppy; double x2 = resint::tau*expmy; //PDFs double fx1[2*MAXNF+1],fx2[2*MAXNF+1]; fdist_(opts.ih1,x1,muf,fx1); fdist_(opts.ih2,x2,muf,fx2); for (int sp = 0; sp < mesq::totpch; sp++) fun += fx1[mesq::pid1[sp]]*fx2[mesq::pid2[sp]]*real(mesq::mesqij[sp])*gr::www[opts.yrule-1][j]*xm;; } } } invres = fun*real(factorfin); } else //1d mellin if (opts.mellin1d) { //double q2 = resint::_m*resint::_m; //double bjx= q2/pow(opts.sroot,2); //double ax = log(bjx); for (int i = 0; i < mellinint::mdim; i++) { pdfevol::retrieve1d(i,mesq::positive); mellinint::pdf_mesq_expy(i,i,mesq::positive); double int1 = mellinint::integrand1d(i); // pdfevol::retrieve1d(i,mesq::negative); //--> both branches are negative // mellinint::pdf_mesq_expy(i,i,mesq::negative); // complex int2 = mellinint::integrand1d(i,mesq::negative); // fun += 0.5*real(int1-int2); //fun += 0.5*(int1-int2); //cout << "C++ " << setprecision(16) << i1 << " " << i2 << " " << int1 << " " << int2 << endl; //do not actually need the negative branch, because it is equal to the complex conjugate of the positive branch //so the sum of the two branches is equal to the real part of the positive branch: 1/2(a+conj(a)) = real(a) fun += int1; //cout << "mellin 1d " << setprecision(16) << i << " " << int1 << endl; } //cout << "besselint 1d inversion " << fun << endl; //invres = fun*real(factorfin); invres = fun*factorfin; //invres = real(factorfin)/resint::_m*(8./3.)*pow(opts.sroot,2)/2.; // --> Check unitarity of Sudakov integral } else { #pragma omp parallel for reduction(+:fun) num_threads(opts.mellincores) copyin(creno_,mesq::mesqij_expy,hcoefficients::Hqqb,hcoefficients::Hqg_1,hcoefficients::Hqg_2,hcoefficients::Hgg,hcoefficients::Hqq,hcoefficients::Hqq_1,hcoefficients::Hqq_2,hcoefficients::Hqqp_1,hcoefficients::Hqqp_2) for (int i1 = 0; i1 < mellinint::mdim; i1++) { pdfevol::retrieve_beam1(i1); for (int i2 = 0; i2 < mellinint::mdim; i2++) { // here scale2 is fixed (b-dependent), and the function is called many times at I1 I2 points // part of the coefficients calculation is hoisted in the previous i loop // --> merge positive and negative branch? // In Rapidity integrated mode: // sigmaij are fatorised from HCRN and numerical integration in y is performed in rapintegrals // the full expression is HCRN(I1,I2)_ij * ccex(I1,I2) * sigma_ij // HCRN(I1,I2)_ij is only b dependent // ccex(I1,I2) is rapidity and mass dependent // sigma_ij is costh and mass dependent, but becomes rapidity dependent after integration of the costh moments // The integrals are solved analitically when no cuts on the leptons are applied //pdfevol::retrieve(i1,i2,mesq::positive); pdfevol::retrieve_beam2_pos(i2); mellinint::pdf_mesq_expy(i1,i2,mesq::positive); double int1 = real(mellinint::integrand2d(i1,i2,mesq::positive)); //pdfevol::retrieve(i1,i2,mesq::negative); pdfevol::retrieve_beam2_neg(); mellinint::pdf_mesq_expy(i1,i2,mesq::negative); double int2 = real(mellinint::integrand2d(i1,i2,mesq::negative)); //fun += -real(0.5*(int1-int2)); fun += -0.5*(int1-int2); //cout << "C++ " << setprecision(16) << i1 << " " << i2 << " " << int1 << " " << int2 << endl; } } //invres = fun*real(factorfin); invres = fun*factorfin; } //cout << "invres " << b << " " << fun << " " << factorfin << " " << invres << endl; if (isnan_ofast(real(invres)) || isnan_ofast(imag(invres))) { cout << "Warning, invres = " << invres << ", qt = " << qt << ", b = " << b << ", pdf*mesq = " << fun << ", S*bj0 = " << factorfin << endl; invres = 0; } //cout << setprecision(16) << "C++ " << b << " " << invres << " " << fun << " " << factorfin << endl; //cout << setprecision(16) << " b " << b << " bstar " << bstar << " besselint " << invres << " J0 " << fort_besj0_(qtb) << " sud " << sudak << " fun " << fun << endl; return invres; } diff --git a/resum/mellinint.C b/resum/mellinint.C index a1fc94e..ed63617 100644 --- a/resum/mellinint.C +++ b/resum/mellinint.C @@ -1,1130 +1,1137 @@ #include "mellinint.h" #include "mesq.h" #include "settings.h" #include "gaussrules.h" #include "clenshawcurtisrules.h" #include "hcoefficients.h" #include "hcoeff.h" #include "pdfevol.h" #include "interface.h" #include "anomalous.h" #include "parton.h" #include "string.h" #include #include #include using namespace parton; //double *mellinint::wn; complex *mellinint::wn; complex *mellinint::Np; complex *mellinint::Nm; complex mellinint::CCp; complex mellinint::CCm; complex mellinint::GGN; complex mellinint::QGN_1; complex mellinint::QGN_2; complex mellinint::QQBN; complex mellinint::QQN; complex mellinint::QQN_1; complex mellinint::QQN_2; complex mellinint::QQPN_1; complex mellinint::QQPN_2; int mellinint::mdim; //fortran interfaces void mellinint_pdf_mesq_expy_(int& i1, int& i2, int& sign) { mellinint::pdf_mesq_expy(i1-1, i2-1, sign-1); }; fcomplex mellinint_integrand_(int& i1, int& i2, int& sign) { return fcx(mellinint::integrand2d(i1-1, i2-1, sign-1)); }; +void mellinint::release() +{ + delete[] wn; + delete[] Np; + delete[] Nm; +} + void mellinint::initgauss() { //set up weights and nodes for gaussian quadrature //cpoint is the starting point on the real axis for the positive and negative part of the integration path //phi is the angle in the complex plane of the positive part of the integration path double cpoint = opts.cpoint; //double phi = M_PI * 1./2.; //double phi = M_PI * 3./4.; double phi = M_PI * opts.phi; double zmin = 0; //upper limit for the mellin integration in the complex plane (z) //Above 50 the integral becomes unstable, especially when m_ll << mur, //due to large logs in the Sudakov, which can be reduced with smaller blim. //The issue can be avoided by using dynamicscale //Also, larger values of zmax requires more support points for the //Mellin inverse transform, i.e. higher mellinintervals or mellinrule. double zmax = opts.zmax; mdim = opts.mellinintervals*opts.mellinrule; //allocate memory //wn = new double [mdim]; wn = new complex [mdim]; Np = new complex [mdim]; Nm = new complex [mdim]; //initialise to 0 for (int i=0; i < mdim; i++) { Np[i]=cpoint+1.; Nm[i]=cpoint+1.; wn[i]=0; } //imaginary unit complex ii = complex (0.,1.); //Gauss-Legendre quadrature along a linear contour if (opts.mellininv == 0) { // positive branch CCp = complex (cos(phi), sin(phi)); for (int i=0; i < opts.mellinintervals; i++) { double a = 0.+(1.-0.)*i/opts.mellinintervals; double b = 0.+(1.-0.)*(i+1)/opts.mellinintervals; double c = 0.5*(a+b); double m = 0.5*(b-a); for (int j=0; j < opts.mellinrule; j++) { double x = c+m*gr::xxx[opts.mellinrule-1][j]; //double x = c+m*cc::xxx[opts.mellinrule-1][j]; double t = zmin+(zmax-zmin)*x; double jac = zmax-zmin; Np[j+i*opts.mellinrule]=complex (cpoint+cos(phi)*t+1.,sin(phi)*t); wn[j+i*opts.mellinrule]=gr::www[opts.mellinrule-1][j]*m*jac; //wn[j+i*opts.mellinrule]=cc::www[opts.mellinrule-1][j]*m*jac; //cout << setprecision(16) << t << " " << Np[j+i*opts.mellinrule] << " " << wn[j+i*opts.mellinrule] << endl; } } // negative branch CCm = complex (cos(phi), -sin(phi)); for (int i=0; i < opts.mellinintervals; i++) { double a = 0.+(1.-0.)*i/opts.mellinintervals; double b = 0.+(1.-0.)*(i+1)/opts.mellinintervals; double c = 0.5*(a+b); double m = 0.5*(b-a); for (int j=0; j < opts.mellinrule; j ++) { double x = c+m*gr::xxx[opts.mellinrule-1][j]; //double x = c+m*cc::xxx[opts.mellinrule-1][j]; double t = zmin+(zmax-zmin)*x; Nm[j+i*opts.mellinrule]=complex (cpoint+cos(phi)*t+1.,-sin(phi)*t); //cout << setprecision(16) << t << " " << Nm[j+i*opts.mellinrule] << endl; } } } //Talbot contour else if (opts.mellininv == 1) { //calculate the range of the corresponding Laplace transform double xmin, xmax; double t0, t1; //could restrict xmin and xmax further for limited y range xmin = pow(bins.mbins.front()/opts.sroot,2); xmax = 1; t0 = -log(xmax); t1 = -log(xmin); double tmid = (t0+t1)/2.; double Not, sigma, lambda, nu, alpha, mu; //fixed talbot of Peter Valko' //lambda = 2*opts.mellinrule/(5*tmid); //nu = 1.; //Modified Talbot of Rizzardi //lambda = 4.8/tmid; //nu = 1.; //Empirically good for Talbot sigma = 0.6; lambda = 0.6; nu = 2.5; //Weideman //Not = opts.mellinrule/tmid; //sigma = -0.6122; //mu = 0.5017; //alpha = 0.6407; //nu = 0.2645; //Empirically good for Weideman //Not = 1.; //sigma = 0.6; //mu = 0.8; //alpha = 1.; //nu = 2.; bool midpoint = false; bool weideman = false; CCp = 1; for (int j=0; j < opts.mellinrule; j++) { double x; if (midpoint) x = (double(j)+0.5)/opts.mellinrule; //midpoint else x = double(j)/opts.mellinrule; //trapezoidal double thmax = M_PI; double theta = thmax*x; complex s, jac; if (weideman) { //Weideman contour s = Not*(sigma+(theta==0?mu/alpha:mu*theta/tan(alpha*theta)+theta*nu*ii)); jac = thmax * Not * (ii * nu + (theta==0?0 : mu * (1./tan(alpha*theta) - alpha*theta*(1. + 1./tan(alpha*theta)/tan(alpha*theta))))); } else { //Talbot contour s = sigma+(theta==0?lambda:lambda*theta*(1./tan(theta)+nu*ii)); jac = thmax * (theta==0? ii*lambda*nu : ii * lambda *( nu + ii * (theta + (theta /tan(theta) - 1.) / tan(theta)))); } Np[j] = s+1.; if (midpoint) wn[j] = jac/double(opts.mellinrule); //midpoint else wn[j] = (j==0 ? jac/2.:jac)/double(opts.mellinrule); //trapezoidal //cout << setprecision(16) << theta << " " << Np[j] << " " << wn[j] << endl; /* double x = 0.5+0.5*gr::xxx[opts.mellinrule-1][j]; double t = zmin+(zmax-zmin)*x; complex jac = (zmax-zmin) * (cos(phi)+ii*sin(phi)); complex s = cpoint + t * (cos(phi)+ii*sin(phi)); Np[j] = s + 1.; wn[j] = gr::www[opts.mellinrule-1][j]*0.5*jac; cout << setprecision(16) << t << " " << Np[j] << " " << wn[j] << endl; */ } // negative branch CCm = 1; for (int j=0; j < opts.mellinrule; j ++) { double x; if (midpoint) x = (double(j)+0.5)/opts.mellinrule; //midpoint else x = double(j)/opts.mellinrule; //trapezoidal double thmax = -M_PI; double theta = thmax*x; complex s; if (weideman) //Weideman contour s = Not*(sigma+(theta==0?mu/alpha:mu*theta/tan(alpha*theta)+theta*nu*ii)); else//Talbot contour s = sigma+(theta==0?lambda:lambda*theta*(1./tan(theta)+nu*ii)); Nm[j] = s+1.; //cout << setprecision(16) << theta << " " << Nm[j] << " " << wn[j] << endl; /* double x = 0.5+0.5*gr::xxx[opts.mellinrule-1][j]; double t = zmin+(zmax-zmin)*x; complex s = cpoint + t * (cos(phi)-ii*sin(phi)); Nm[j] = s + 1.; cout << setprecision(16) << t << " " << Nm[j] << endl; */ } } else { //Implement here other mellin inversions cout << "Not valid option for mellininv (should be 0 or 1) " << endl; exit (-1); } } //This function performs the product of PDF, born level amplitudes and expy piece, and sums over partonic channels (i,j) //It is a function of z1 and z2 in Mellin space // The integrand of the inverse Mellin transform is composed of // A) parton luminosities in Mellin space: fn1 * fn2 -> GGN, QGN, QQBN, QQN, QQPN which are functions of the quark flavours (i,j) and Mellin indices (i1, i2) // B) the EW born level squared amplitudes mesq::mesqij, which are functions of m, costh and quark flavours (i,j) (if integrated in costh, and in the presence of cuts on the leptons, the costh moments are functions of y, pt, m) // C) the x1^-z1 * x2^-z2 piece of the Mellin inverse transform, which depends explicitly on rapidity and on the Mellin indices (i1, i2) // D) the Wilson coefficients Hgg, Hqqb, etc.. which are functions of the Mellin indices (i1, i2) //In mode = 1, the integration in costh and phi enters only in B //In mode = 2, the integration in costh, phi and rapidity enters in B and C, hence B and C are calculated together in mesq::mesqij_expy //The product with the Wilson coefficients (D) can be performed at the very end, in mellinint::integrand //input : pdfevol::fn1, pdfevol::fn2, mesq::mesqij_expy //output: qqbn, qgn, ggn //#define fn1(x) pdfevol::fx1[i1*11+x] //#define fn2(x) pdfevol::fx2[i2*11+x] void mellinint::pdf_mesq_expy(int i1, int i2, int sign) { //QQBN=0; if (opts.order < 1) { QGN_1=0; QGN_2=0; } if (opts.order < 2) { GGN=0; //QQN=0; QQN_1=0; QQN_2=0; QQPN_1=0; QQPN_2=0; } complex* fn1 = pdfevol::fn1; complex* fn2 = pdfevol::fn2; //complex fn1[11]; //complex fn2[11]; //memcpy(fn1, &(pdfevol::fx1[i1*11]), 11*sizeof(complex)); //if (sign == mesq::positive) //memcpy(fn2, &(pdfevol::fx2[i2*11]), 11*sizeof(complex)); //else //memcpy(fn2, &(pdfevol::fx2[mellinint::mdim*11+i2*11]), 11*sizeof(complex)); //set b to 0 // fn2[bb] = 0; fn1[bb] = 0; // fn2[b ] = 0; fn1[b ] = 0; //set s and c to 0 // fn2[cb] = 0; fn1[cb] = 0; // fn2[sb] = 0; fn1[sb] = 0; // fn2[s ] = 0; fn1[s ] = 0; // fn2[c ] = 0; fn1[c ] = 0; //set u and d to 0 // fn2[db] = 0; fn1[db] = 0; // fn2[ub] = 0; fn1[ub] = 0; // fn2[u ] = 0; fn1[u ] = 0; // fn2[d ] = 0; fn1[d ] = 0; //set gluon to 0 // fn2[g] = 0; fn1[g] = 0; //DYRES convention // bb cb sb db ub g u d s c b // -5 -4 -3 -2 -1 0 1 2 3 4 5 //mesqij[n] -> mesqij_expy[mesq::index(n,i1,i2,sign)] if (opts.nproc == 3) { complex mesq_uub = mesq::mesqij_expy[mesq::index(0,i1,i2,sign)]; complex mesq_ubu = mesq::mesqij_expy[mesq::index(1,i1,i2,sign)]; complex mesq_ddb = mesq::mesqij_expy[mesq::index(2,i1,i2,sign)]; complex mesq_dbd = mesq::mesqij_expy[mesq::index(3,i1,i2,sign)]; complex mesq_ssb = mesq::mesqij_expy[mesq::index(4,i1,i2,sign)]; complex mesq_sbs = mesq::mesqij_expy[mesq::index(5,i1,i2,sign)]; complex mesq_ccb = mesq::mesqij_expy[mesq::index(6,i1,i2,sign)]; complex mesq_cbc = mesq::mesqij_expy[mesq::index(7,i1,i2,sign)]; complex mesq_bbr = mesq::mesqij_expy[mesq::index(8,i1,i2,sign)]; complex mesq_brb = mesq::mesqij_expy[mesq::index(9,i1,i2,sign)]; // cout << "pdf_mesq_expy " << i1 << " " << i2 << " " << mesq_uub << " " << fn1[u] << " " << fn2[ub] << endl; //LL part QQBN = fn1[u ]*fn2[ub]*mesq_uub +fn1[c ]*fn2[cb]*mesq_ccb +fn1[d ]*fn2[db]*mesq_ddb +fn1[s ]*fn2[sb]*mesq_ssb +fn1[b ]*fn2[bb]*mesq_bbr +fn1[ub]*fn2[u ]*mesq_ubu +fn1[cb]*fn2[c ]*mesq_cbc +fn1[db]*fn2[d ]*mesq_dbd +fn1[sb]*fn2[s ]*mesq_sbs +fn1[bb]*fn2[b ]*mesq_brb; //NLL part if(opts.order >= 1) { QGN_1 = fn1[g]*(fn2[ub]*mesq_uub +fn2[cb]*mesq_ccb +fn2[db]*mesq_ddb +fn2[sb]*mesq_ssb +fn2[bb]*mesq_bbr +fn2[u]*mesq_ubu +fn2[c]*mesq_cbc +fn2[d]*mesq_dbd +fn2[s]*mesq_sbs +fn2[b]*mesq_brb); QGN_2 = fn2[g]*(fn1[u]*mesq_uub +fn1[c]*mesq_ccb +fn1[d]*mesq_ddb +fn1[s]*mesq_ssb +fn1[b]*mesq_bbr +fn1[ub]*mesq_ubu +fn1[cb]*mesq_cbc +fn1[db]*mesq_dbd +fn1[sb]*mesq_sbs +fn1[bb]*mesq_brb); } //NNLL if(opts.order >= 2) { GGN = fn1[g]*fn2[g]* (mesq_uub + mesq_ccb + mesq_ddb + mesq_ssb + mesq_bbr + mesq_ubu + mesq_cbc + mesq_dbd + mesq_sbs + mesq_brb); //I suspect a mistake here: there are different costh couplings for u-ubar and ubar-u, //the contribution u u -> ub u and u u -> u ub should be separated (need to split hqq_1 and hqq_2) /* QQN = fn1[u]*fn2[u]*mesq_uub +fn1[c]*fn2[c]*mesq_ccb +fn1[d]*fn2[d]*mesq_ddb +fn1[s]*fn2[s]*mesq_ssb +fn1[b]*fn2[b]*mesq_bbr +fn1[ub]*fn2[ub]*mesq_ubu +fn1[cb]*fn2[cb]*mesq_cbc +fn1[db]*fn2[db]*mesq_dbd +fn1[sb]*fn2[sb]*mesq_sbs +fn1[bb]*fn2[bb]*mesq_brb; */ QQN_1 = fn1[u]*fn2[u]*mesq_ubu +fn1[c]*fn2[c]*mesq_cbc +fn1[d]*fn2[d]*mesq_dbd +fn1[s]*fn2[s]*mesq_sbs +fn1[b]*fn2[b]*mesq_brb +fn1[ub]*fn2[ub]*mesq_uub +fn1[cb]*fn2[cb]*mesq_ccb +fn1[db]*fn2[db]*mesq_ddb +fn1[sb]*fn2[sb]*mesq_ssb +fn1[bb]*fn2[bb]*mesq_bbr; QQN_2 = fn1[u]*fn2[u]*mesq_uub +fn1[c]*fn2[c]*mesq_ccb +fn1[d]*fn2[d]*mesq_ddb +fn1[s]*fn2[s]*mesq_ssb +fn1[b]*fn2[b]*mesq_bbr +fn1[ub]*fn2[ub]*mesq_ubu +fn1[cb]*fn2[cb]*mesq_cbc +fn1[db]*fn2[db]*mesq_dbd +fn1[sb]*fn2[sb]*mesq_sbs +fn1[bb]*fn2[bb]*mesq_brb; QQPN_1 = fn1[u]*(fn2[db]*mesq_ddb +fn2[sb]*mesq_ssb +fn2[cb]*mesq_ccb +fn2[bb]*mesq_bbr +fn2[d]*mesq_dbd +fn2[s]*mesq_sbs +fn2[c]*mesq_cbc +fn2[b]*mesq_brb) + fn1[d]*(fn2[ub]*mesq_uub +fn2[sb]*mesq_ssb +fn2[cb]*mesq_ccb +fn2[bb]*mesq_bbr +fn2[u]*mesq_ubu +fn2[s]*mesq_sbs +fn2[c]*mesq_cbc +fn2[b]*mesq_brb) + fn1[s]*(fn2[ub]*mesq_uub +fn2[db]*mesq_ddb +fn2[cb]*mesq_ccb +fn2[bb]*mesq_bbr +fn2[u]*mesq_ubu +fn2[d]*mesq_dbd +fn2[c]*mesq_cbc +fn2[b]*mesq_brb) + fn1[c]*(fn2[ub]*mesq_uub +fn2[db]*mesq_ddb +fn2[sb]*mesq_ssb +fn2[bb]*mesq_bbr +fn2[u]*mesq_ubu +fn2[d]*mesq_dbd +fn2[s]*mesq_sbs +fn2[b]*mesq_brb) + fn1[b]*(fn2[ub]*mesq_uub +fn2[db]*mesq_ddb +fn2[sb]*mesq_ssb +fn2[cb]*mesq_ccb +fn2[u]*mesq_ubu +fn2[d]*mesq_dbd +fn2[s]*mesq_sbs +fn2[c]*mesq_cbc) + fn1[ub]*(fn2[db]*mesq_ddb +fn2[sb]*mesq_ssb +fn2[cb]*mesq_ccb +fn2[bb]*mesq_bbr +fn2[d]*mesq_dbd +fn2[s]*mesq_sbs +fn2[c]*mesq_cbc +fn2[b]*mesq_brb) + fn1[db]*(fn2[ub]*mesq_uub +fn2[sb]*mesq_ssb +fn2[cb]*mesq_ccb +fn2[bb]*mesq_bbr +fn2[u]*mesq_ubu +fn2[s]*mesq_sbs +fn2[c]*mesq_cbc +fn2[b]*mesq_brb) + fn1[sb]*(fn2[ub]*mesq_uub +fn2[db]*mesq_ddb +fn2[cb]*mesq_ccb +fn2[bb]*mesq_bbr +fn2[u]*mesq_ubu +fn2[d]*mesq_dbd +fn2[c]*mesq_cbc +fn2[b]*mesq_brb) + fn1[cb]*(fn2[ub]*mesq_uub +fn2[db]*mesq_ddb +fn2[sb]*mesq_ssb +fn2[bb]*mesq_bbr +fn2[u]*mesq_ubu +fn2[d]*mesq_dbd +fn2[s]*mesq_sbs +fn2[b]*mesq_brb) + fn1[bb]*(fn2[ub]*mesq_uub +fn2[db]*mesq_ddb +fn2[sb]*mesq_ssb +fn2[cb]*mesq_ccb +fn2[u]*mesq_ubu +fn2[d]*mesq_dbd +fn2[s]*mesq_sbs +fn2[c]*mesq_cbc); QQPN_2 = fn2[u]*(fn1[d]*mesq_ddb +fn1[s]*mesq_ssb +fn1[c]*mesq_ccb +fn1[b]*mesq_bbr +fn1[db]*mesq_dbd +fn1[sb]*mesq_sbs +fn1[cb]*mesq_cbc +fn1[bb]*mesq_brb) + fn2[d]* (fn1[u]*mesq_uub +fn1[s]*mesq_ssb +fn1[c]*mesq_ccb +fn1[b]*mesq_bbr +fn1[ub]*mesq_ubu +fn1[sb]*mesq_sbs +fn1[cb]*mesq_cbc +fn1[bb]*mesq_brb) + fn2[s]* (fn1[u]*mesq_uub +fn1[d]*mesq_ddb +fn1[c]*mesq_ccb +fn1[b]*mesq_bbr +fn1[ub]*mesq_ubu +fn1[db]*mesq_dbd +fn1[cb]*mesq_cbc +fn1[bb]*mesq_brb) + fn2[c]* (fn1[u]*mesq_uub +fn1[d]*mesq_ddb +fn1[s]*mesq_ssb +fn1[b]*mesq_bbr +fn1[ub]*mesq_ubu +fn1[db]*mesq_dbd +fn1[sb]*mesq_sbs +fn1[bb]*mesq_brb) + fn2[b]* (fn1[u]*mesq_uub +fn1[d]*mesq_ddb +fn1[s]*mesq_ssb +fn1[c]*mesq_ccb +fn1[ub]*mesq_ubu +fn1[db]*mesq_dbd +fn1[sb]*mesq_sbs +fn1[cb]*mesq_cbc) + fn2[ub]*(fn1[d]*mesq_ddb +fn1[s]*mesq_ssb +fn1[c]*mesq_ccb +fn1[b]*mesq_bbr +fn1[db]*mesq_dbd +fn1[sb]*mesq_sbs +fn1[cb]*mesq_cbc +fn1[bb]*mesq_brb) + fn2[db]*(fn1[u]*mesq_uub +fn1[s]*mesq_ssb +fn1[c]*mesq_ccb +fn1[b]*mesq_bbr +fn1[ub]*mesq_ubu +fn1[sb]*mesq_sbs +fn1[cb]*mesq_cbc +fn1[bb]*mesq_brb) + fn2[sb]*(fn1[u]*mesq_uub +fn1[d]*mesq_ddb +fn1[c]*mesq_ccb +fn1[b]*mesq_bbr +fn1[ub]*mesq_ubu +fn1[db]*mesq_dbd +fn1[cb]*mesq_cbc +fn1[bb]*mesq_brb) + fn2[cb]*(fn1[u]*mesq_uub +fn1[d]*mesq_ddb +fn1[s]*mesq_ssb +fn1[b]*mesq_bbr +fn1[ub]*mesq_ubu +fn1[db]*mesq_dbd +fn1[sb]*mesq_sbs +fn1[bb]*mesq_brb) + fn2[bb]*(fn1[u]*mesq_uub +fn1[d]*mesq_ddb +fn1[s]*mesq_ssb +fn1[c]*mesq_ccb +fn1[ub]*mesq_ubu +fn1[db]*mesq_dbd +fn1[sb]*mesq_sbs +fn1[cb]*mesq_cbc); } } if (opts.nproc == 1) { //DYRES convention // bb cb sb db ub g u d s c b // -5 -4 -3 -2 -1 0 1 2 3 4 5 complex mesq_udb = mesq::mesqij_expy[mesq::index(0,i1,i2,sign)]; complex mesq_dbu = mesq::mesqij_expy[mesq::index(1,i1,i2,sign)]; complex mesq_usb = mesq::mesqij_expy[mesq::index(2,i1,i2,sign)]; complex mesq_sbu = mesq::mesqij_expy[mesq::index(3,i1,i2,sign)]; complex mesq_ubb = mesq::mesqij_expy[mesq::index(4,i1,i2,sign)]; complex mesq_bbu = mesq::mesqij_expy[mesq::index(5,i1,i2,sign)]; complex mesq_csb = mesq::mesqij_expy[mesq::index(6,i1,i2,sign)]; complex mesq_sbc = mesq::mesqij_expy[mesq::index(7,i1,i2,sign)]; complex mesq_cdb = mesq::mesqij_expy[mesq::index(8,i1,i2,sign)]; complex mesq_dbc = mesq::mesqij_expy[mesq::index(9,i1,i2,sign)]; complex mesq_cbb = mesq::mesqij_expy[mesq::index(10,i1,i2,sign)]; complex mesq_bbc = mesq::mesqij_expy[mesq::index(11,i1,i2,sign)]; //LL part QQBN = fn1[u ]*fn2[db]*mesq_udb + fn1[u ]*fn2[sb]*mesq_usb + fn1[u ]*fn2[bb]*mesq_ubb + fn1[c ]*fn2[db]*mesq_cdb + fn1[c ]*fn2[sb]*mesq_csb + fn1[c ]*fn2[bb]*mesq_cbb + fn1[db]*fn2[u ]*mesq_dbu + fn1[db]*fn2[c ]*mesq_dbc + fn1[sb]*fn2[u ]*mesq_sbu + fn1[sb]*fn2[c ]*mesq_sbc + fn1[bb]*fn2[u ]*mesq_bbu + fn1[bb]*fn2[c ]*mesq_bbc; // NLL part if(opts.order >= 1) { QGN_1 = fn1[g]*(fn2[db]*mesq_udb + fn2[sb]*mesq_usb + fn2[bb]*mesq_ubb + fn2[db]*mesq_cdb + fn2[sb]*mesq_csb + fn2[bb]*mesq_cbb + fn2[u]*mesq_dbu + fn2[c]*mesq_dbc + fn2[u]*mesq_sbu + fn2[c]*mesq_sbc + fn2[u]*mesq_bbu + fn2[c]*mesq_bbc); QGN_2 = fn2[g]*(fn1[u]*mesq_udb + fn1[u]*mesq_usb + fn1[u]*mesq_ubb + fn1[c]*mesq_cdb + fn1[c]*mesq_csb + fn1[c]*mesq_cbb + fn1[db]*mesq_dbu + fn1[db]*mesq_dbc + fn1[sb]*mesq_sbu + fn1[sb]*mesq_sbc + fn1[bb]*mesq_bbu + fn1[bb]*mesq_bbc); } //NNLL if(opts.order >= 2) { GGN = fn1[g]*fn2[g]* (mesq_udb + mesq_usb + mesq_ubb + mesq_cdb + mesq_csb + mesq_cbb + mesq_dbu + mesq_dbc + mesq_sbu + mesq_sbc + mesq_bbu + mesq_bbc); /* QQN = fn1[u]*fn2[d]*mesq_udb + fn1[u]*fn2[s]*mesq_usb + fn1[u]*fn2[b]*mesq_ubb + fn1[c]*fn2[d]*mesq_cdb + fn1[c]*fn2[s]*mesq_csb + fn1[c]*fn2[b]*mesq_cbb + fn1[db]*fn2[ub]*mesq_dbu + fn1[db]*fn2[cb]*mesq_dbc + fn1[sb]*fn2[ub]*mesq_sbu + fn1[sb]*fn2[cb]*mesq_sbc + fn1[bb]*fn2[ub]*mesq_bbu + fn1[bb]*fn2[cb]*mesq_bbc; */ QQN_1 = fn1[ub]*fn2[db]*mesq_udb + fn1[ub]*fn2[sb]*mesq_usb + fn1[ub]*fn2[bb]*mesq_ubb + fn1[cb]*fn2[db]*mesq_cdb + fn1[cb]*fn2[sb]*mesq_csb + fn1[cb]*fn2[bb]*mesq_cbb + fn1[d]*fn2[u]*mesq_dbu + fn1[d]*fn2[c]*mesq_dbc + fn1[s]*fn2[u]*mesq_sbu + fn1[s]*fn2[c]*mesq_sbc + fn1[b]*fn2[u]*mesq_bbu + fn1[b]*fn2[c]*mesq_bbc; QQN_2 = fn1[u]*fn2[d]*mesq_udb + fn1[u]*fn2[s]*mesq_usb + fn1[u]*fn2[b]*mesq_ubb + fn1[c]*fn2[d]*mesq_cdb + fn1[c]*fn2[s]*mesq_csb + fn1[c]*fn2[b]*mesq_cbb + fn1[db]*fn2[ub]*mesq_dbu + fn1[db]*fn2[cb]*mesq_dbc + fn1[sb]*fn2[ub]*mesq_sbu + fn1[sb]*fn2[cb]*mesq_sbc + fn1[bb]*fn2[ub]*mesq_bbu + fn1[bb]*fn2[cb]*mesq_bbc; QQPN_1 = (fn1[u]+fn1[ub])* ( fn2[db]*mesq_cdb + fn2[sb]*mesq_csb + fn2[bb]*mesq_cbb + fn2[u]*mesq_dbu + fn2[c]*mesq_dbc + fn2[u]*mesq_sbu + fn2[c]*mesq_sbc + fn2[u]*mesq_bbu + fn2[c]*mesq_bbc) + (fn1[d]+fn1[db])* ( fn2[db]*mesq_udb + fn2[sb]*mesq_usb + fn2[bb]*mesq_ubb + fn2[db]*mesq_cdb + fn2[sb]*mesq_csb + fn2[bb]*mesq_cbb + fn2[u]*mesq_sbu + fn2[c]*mesq_sbc + fn2[u]*mesq_bbu + fn2[c]*mesq_bbc) + (fn1[s]+fn1[sb])* ( fn2[db]*mesq_udb + fn2[sb]*mesq_usb + fn2[bb]*mesq_ubb + fn2[db]*mesq_cdb + fn2[sb]*mesq_csb + fn2[bb]*mesq_cbb + fn2[u]*mesq_dbu + fn2[c]*mesq_dbc + fn2[u]*mesq_bbu + fn2[c]*mesq_bbc) + (fn1[c]+fn1[cb])* ( fn2[db]*mesq_udb + fn2[sb]*mesq_usb + fn2[bb]*mesq_ubb + fn2[u]*mesq_dbu + fn2[c]*mesq_dbc + fn2[u]*mesq_sbu + fn2[c]*mesq_sbc + fn2[u]*mesq_bbu + fn2[c]*mesq_bbc) + (fn1[b]+fn1[bb])* ( fn2[db]*mesq_udb + fn2[sb]*mesq_usb + fn2[bb]*mesq_ubb + fn2[db]*mesq_cdb + fn2[sb]*mesq_csb + fn2[bb]*mesq_cbb + fn2[u]*mesq_dbu + fn2[c]*mesq_dbc + fn2[u]*mesq_sbu + fn2[c]*mesq_sbc); QQPN_2 = (fn2[u]+fn2[ub])* (fn1[u]*mesq_udb + fn1[u]*mesq_usb + fn1[u]*mesq_ubb + fn1[c]*mesq_cdb + fn1[c]*mesq_csb + fn1[c]*mesq_cbb + fn1[db]*mesq_dbc + fn1[sb]*mesq_sbc + fn1[bb]*mesq_bbc) + (fn2[d]+fn2[db])* (fn1[u]*mesq_usb + fn1[u]*mesq_ubb + fn1[c]*mesq_csb + fn1[c]*mesq_cbb + fn1[db]*mesq_dbu + fn1[db]*mesq_dbc + fn1[sb]*mesq_sbu + fn1[sb]*mesq_sbc + fn1[bb]*mesq_bbu + fn1[bb]*mesq_bbc) + (fn2[s]+fn2[sb])* (fn1[u]*mesq_udb + fn1[u]*mesq_ubb + fn1[c]*mesq_cdb + fn1[c]*mesq_cbb + fn1[db]*mesq_dbu + fn1[db]*mesq_dbc + fn1[sb]*mesq_sbu + fn1[sb]*mesq_sbc + fn1[bb]*mesq_bbu + fn1[bb]*mesq_bbc) + (fn2[c]+fn2[cb])* (fn1[u]*mesq_udb + fn1[u]*mesq_usb + fn1[u]*mesq_ubb + fn1[c]*mesq_cdb + fn1[c]*mesq_csb + fn1[c]*mesq_cbb + fn1[db]*mesq_dbu + fn1[sb]*mesq_sbu + fn1[bb]*mesq_bbu) + (fn2[b]+fn2[bb])* (fn1[u]*mesq_udb + fn1[u]*mesq_usb + fn1[c]*mesq_cdb + fn1[c]*mesq_csb + fn1[db]*mesq_dbu + fn1[db]*mesq_dbc + fn1[sb]*mesq_sbu + fn1[sb]*mesq_sbc + fn1[bb]*mesq_bbu + fn1[bb]*mesq_bbc); } } if (opts.nproc == 2) { //DYRES convention // bb cb sb db ub g u d s c b // -5 -4 -3 -2 -1 0 1 2 3 4 5 complex mesq_dub = mesq::mesqij_expy[mesq::index(0,i1,i2,sign)]; complex mesq_ubd = mesq::mesqij_expy[mesq::index(1,i1,i2,sign)]; complex mesq_sub = mesq::mesqij_expy[mesq::index(2,i1,i2,sign)]; complex mesq_ubs = mesq::mesqij_expy[mesq::index(3,i1,i2,sign)]; complex mesq_bub = mesq::mesqij_expy[mesq::index(4,i1,i2,sign)]; complex mesq_ubb = mesq::mesqij_expy[mesq::index(5,i1,i2,sign)]; complex mesq_scb = mesq::mesqij_expy[mesq::index(6,i1,i2,sign)]; complex mesq_cbs = mesq::mesqij_expy[mesq::index(7,i1,i2,sign)]; complex mesq_dcb = mesq::mesqij_expy[mesq::index(8,i1,i2,sign)]; complex mesq_cbd = mesq::mesqij_expy[mesq::index(9,i1,i2,sign)]; complex mesq_bcb = mesq::mesqij_expy[mesq::index(10,i1,i2,sign)]; complex mesq_cbb = mesq::mesqij_expy[mesq::index(11,i1,i2,sign)]; //LL part QQBN = fn1[ub]*fn2[d]*mesq_ubd + fn1[ub]*fn2[s]*mesq_ubs + fn1[ub]*fn2[b]*mesq_ubb + fn1[cb]*fn2[d]*mesq_cbd + fn1[cb]*fn2[s]*mesq_cbs + fn1[cb]*fn2[b]*mesq_cbb + fn1[d]*fn2[ub]*mesq_dub + fn1[d]*fn2[cb]*mesq_dcb + fn1[s]*fn2[ub]*mesq_sub + fn1[s]*fn2[cb]*mesq_scb + fn1[b]*fn2[ub]*mesq_bub + fn1[b]*fn2[cb]*mesq_bcb; // NLL part if(opts.order >= 1) { QGN_1 = fn1[g]*(fn2[d]*mesq_ubd + fn2[s]*mesq_ubs + fn2[b]*mesq_ubb + fn2[d]*mesq_cbd + fn2[s]*mesq_cbs + fn2[b]*mesq_cbb + fn2[ub]*mesq_dub + fn2[cb]*mesq_dcb + fn2[ub]*mesq_sub + fn2[cb]*mesq_scb + fn2[ub]*mesq_bub + fn2[cb]*mesq_bcb); QGN_2 = fn2[g]*(fn1[ub]*mesq_ubd + fn1[ub]*mesq_ubs + fn1[ub]*mesq_ubb + fn1[cb]*mesq_cbd + fn1[cb]*mesq_cbs + fn1[cb]*mesq_cbb + fn1[d]*mesq_dub + fn1[d]*mesq_dcb + fn1[s]*mesq_sub + fn1[s]*mesq_scb + fn1[b]*mesq_bub + fn1[b]*mesq_bcb); } //NNLL if(opts.order >= 2) { GGN = fn1[g]*fn2[g]* (mesq_ubd + mesq_ubs + mesq_ubb + mesq_cbd + mesq_cbs + mesq_cbb + mesq_dub + mesq_dcb + mesq_sub + mesq_scb + mesq_bub + mesq_bcb); /* QQN = fn1[ub]*fn2[db]*mesq_ubd + fn1[ub]*fn2[sb]*mesq_ubs + fn1[ub]*fn2[bb]*mesq_ubb + fn1[cb]*fn2[db]*mesq_cbd + fn1[cb]*fn2[sb]*mesq_cbs + fn1[cb]*fn2[bb]*mesq_cbb + fn1[d]*fn2[u]*mesq_dub + fn1[d]*fn2[c]*mesq_dcb + fn1[s]*fn2[u]*mesq_sub + fn1[s]*fn2[c]*mesq_scb + fn1[b]*fn2[u]*mesq_bub + fn1[b]*fn2[c]*mesq_bcb; */ QQN_1 = fn1[u]*fn2[d]*mesq_ubd + fn1[u]*fn2[s]*mesq_ubs + fn1[u]*fn2[b]*mesq_ubb + fn1[c]*fn2[d]*mesq_cbd + fn1[c]*fn2[s]*mesq_cbs + fn1[c]*fn2[b]*mesq_cbb + fn1[db]*fn2[ub]*mesq_dub + fn1[db]*fn2[cb]*mesq_dcb + fn1[sb]*fn2[ub]*mesq_sub + fn1[sb]*fn2[cb]*mesq_scb + fn1[bb]*fn2[ub]*mesq_bub + fn1[bb]*fn2[cb]*mesq_bcb; QQN_2 = fn1[ub]*fn2[db]*mesq_ubd + fn1[ub]*fn2[sb]*mesq_ubs + fn1[ub]*fn2[bb]*mesq_ubb + fn1[cb]*fn2[db]*mesq_cbd + fn1[cb]*fn2[sb]*mesq_cbs + fn1[cb]*fn2[bb]*mesq_cbb + fn1[d]*fn2[u]*mesq_dub + fn1[d]*fn2[c]*mesq_dcb + fn1[s]*fn2[u]*mesq_sub + fn1[s]*fn2[c]*mesq_scb + fn1[b]*fn2[u]*mesq_bub + fn1[b]*fn2[c]*mesq_bcb; QQPN_1 = (fn1[ub]+fn1[u])* ( fn2[d]*mesq_cbd + fn2[s]*mesq_cbs + fn2[b]*mesq_cbb + fn2[ub]*mesq_dub + fn2[cb]*mesq_dcb + fn2[ub]*mesq_sub + fn2[cb]*mesq_scb + fn2[ub]*mesq_bub + fn2[cb]*mesq_bcb) + (fn1[db]+fn1[d])* ( fn2[d]*mesq_ubd + fn2[s]*mesq_ubs + fn2[b]*mesq_ubb + fn2[d]*mesq_cbd + fn2[s]*mesq_cbs + fn2[b]*mesq_cbb + fn2[ub]*mesq_sub + fn2[cb]*mesq_scb + fn2[ub]*mesq_bub + fn2[cb]*mesq_bcb) + (fn1[sb]+fn1[s])* ( fn2[d]*mesq_ubd + fn2[s]*mesq_ubs + fn2[b]*mesq_ubb + fn2[d]*mesq_cbd + fn2[s]*mesq_cbs + fn2[b]*mesq_cbb + fn2[ub]*mesq_dub + fn2[cb]*mesq_dcb + fn2[ub]*mesq_bub + fn2[cb]*mesq_bcb) + (fn1[cb]+fn1[c])* ( fn2[d]*mesq_ubd + fn2[s]*mesq_ubs + fn2[b]*mesq_ubb + fn2[ub]*mesq_dub + fn2[cb]*mesq_dcb + fn2[ub]*mesq_sub + fn2[cb]*mesq_scb + fn2[ub]*mesq_bub + fn2[cb]*mesq_bcb) + (fn1[bb]+fn1[b])* ( fn2[d]*mesq_ubd + fn2[s]*mesq_ubs + fn2[b]*mesq_ubb + fn2[d]*mesq_cbd + fn2[s]*mesq_cbs + fn2[b]*mesq_cbb + fn2[ub]*mesq_dub + fn2[cb]*mesq_dcb + fn2[ub]*mesq_sub + fn2[cb]*mesq_scb); QQPN_2 = (fn2[ub]+fn2[u])* (fn1[ub]*mesq_ubd + fn1[ub]*mesq_ubs + fn1[ub]*mesq_ubb + fn1[cb]*mesq_cbd + fn1[cb]*mesq_cbs + fn1[cb]*mesq_cbb + fn1[d]*mesq_dcb + fn1[s]*mesq_scb + fn1[b]*mesq_bcb) + (fn2[db]+fn2[d])* (fn1[ub]*mesq_ubs + fn1[ub]*mesq_ubb + fn1[cb]*mesq_cbs + fn1[cb]*mesq_cbb + fn1[d]*mesq_dub + fn1[d]*mesq_dcb + fn1[s]*mesq_sub + fn1[s]*mesq_scb + fn1[b]*mesq_bub + fn1[b]*mesq_bcb) + (fn2[sb]+fn2[s])* (fn1[ub]*mesq_ubd + fn1[ub]*mesq_ubb + fn1[cb]*mesq_cbd + fn1[cb]*mesq_cbb + fn1[d]*mesq_dub + fn1[d]*mesq_dcb + fn1[s]*mesq_sub + fn1[s]*mesq_scb + fn1[b]*mesq_bub + fn1[b]*mesq_bcb) + (fn2[cb]+fn2[c])* (fn1[ub]*mesq_ubd + fn1[ub]*mesq_ubs + fn1[ub]*mesq_ubb + fn1[cb]*mesq_cbd + fn1[cb]*mesq_cbs + fn1[cb]*mesq_cbb + fn1[d]*mesq_dub + fn1[s]*mesq_sub + fn1[b]*mesq_bub) + (fn2[bb]+fn2[b])* (fn1[ub]*mesq_ubd + fn1[ub]*mesq_ubs + fn1[cb]*mesq_cbd + fn1[cb]*mesq_cbs + fn1[d]*mesq_dub + fn1[d]*mesq_dcb + fn1[s]*mesq_sub + fn1[s]*mesq_scb + fn1[b]*mesq_bub + fn1[b]*mesq_bcb); } } } double mellinint::integrand2d(int i1, int i2, int sign) { //cout << "C++ " << i1 << " " << i2 << " " << QQBN << endl; if (opts.order == 0) return real(QQBN); int i = hcoefficients::index(i1,i2,sign); //cout << "C++ " << i1 << " " << i2 << " " << GGN << " " << hcoefficients::Hgg[i] << endl; return //contribution starting at LL real(QQBN*hcoefficients::Hqqb[i]) //contribution starting at NLL + real(QGN_1*hcoefficients::Hqg_1[i]) + real(QGN_2*hcoefficients::Hqg_2[i]) //contributions starting at NNLL + real(GGN*hcoefficients::Hgg[i]) //+ QQN*hcoefficients::Hqq[i] + real(QQN_1*hcoefficients::Hqq_1[i]) + real(QQN_2*hcoefficients::Hqq_2[i]) //Bug fix in DYRES (I believe this is more correct, since it accounts for which leg undergoes the q -> qb or qb -> q transformation) + real(QQPN_1*hcoefficients::Hqqp_1[i]) + real(QQPN_2*hcoefficients::Hqqp_2[i]); } double mellinint::integrand1d(int i) { // cout << i << " " << QQBN << endl; if (opts.order == 0) return real(QQBN); return //contribution starting at LL real(QQBN*hcoeff::Hqqb[i]) //contribution starting at NLL + real((QGN_1+QGN_2)*hcoeff::Hqg[i]) //contributions starting at NNLL + real(GGN*hcoeff::Hgg[i]) //+ QQN*hcoeff::Hqq[i] + real((QQN_1+QQN_2)*hcoeff::Hqq[i]) //Bug fix in DYRES (I believe this is more correct, since it accounts for which leg undergoes the q -> qb or qb -> q transformation) + real((QQPN_1+QQPN_2)*hcoeff::Hqqp[i]); } //Failed attempt to perform N to z Mellin inversion before PDF convolution /* complex mellinint::integrand() { if (opts.order == 0) return QQBN; // cout << "mellinint:integrand()" << QQBN << " " << hcoeff::Hqqbz << endl; return //contribution starting at LL QQBN*hcoeff::Hqqbz //contribution starting at NLL + (QGN_1+QGN_2)*hcoeff::Hqgz //contributions starting at NNLL + GGN*hcoeff::Hggz + QQN*hcoeff::Hqqz //+ (QQN_1+QQN_2)*hcoeff::Hqqz //I believe this is more correct, since it accounts for which leg undergoes the q -> qb or qb -> q transformation + (QQPN_1+QQPN_2)*hcoeff::Hqqpz; } */ diff --git a/resum/mellinint.h b/resum/mellinint.h index f36de6d..76cc5fa 100644 --- a/resum/mellinint.h +++ b/resum/mellinint.h @@ -1,48 +1,49 @@ #ifndef mellinint_h #define mellinint_h #include "fcomplex.h" #include #include //fortran interfaces extern "C" { void mellinint_pdf_mesq_expy_(int& i1, int& i2, int& sign); fcomplex mellinint_integrand_(int& i1, int& i2, int& sign); } using namespace std; namespace mellinint { extern int mdim; //extern double *wn; //weights of the gaussian quadrature rule extern complex *wn; //weights of the gaussian quadrature rule extern complex *Np; //nodes on the positive branch of the contour extern complex *Nm; //nodes on the negative branch of the contour extern complex CCp,CCm; //angles of the positive and negative branches in the unitary complex circle extern void initgauss(); + extern void release(); extern void pdf_mesq_expy(int i1, int i2, int sign); extern double integrand2d(int i1, int i2, int sign); extern double integrand1d(int i); // extern complex integrand(); inline int index(int i1, int i2) {return i2 + mellinint::mdim*i1;} //luminosity times mesqij extern complex GGN; extern complex QGN_1; extern complex QGN_2; extern complex QQBN; extern complex QQN; extern complex QQN_1; extern complex QQN_2; extern complex QQPN_1; extern complex QQPN_2; #pragma omp threadprivate(GGN,QGN_1,QGN_2,QQBN,QQN,QQN_1,QQN_2,QQPN_1,QQPN_2) } #endif diff --git a/resum/pdfevol.C b/resum/pdfevol.C index 2d37b58..f3bf49a 100644 --- a/resum/pdfevol.C +++ b/resum/pdfevol.C @@ -1,1382 +1,1388 @@ #include "pdfevol.h" #include "interface.h" #include "settings.h" #include "mesq.h" #include "anomalous.h" #include "resconst.h" #include "chebyshev.h" #include "phasespace.h" #include "mellinpdf.h" #include "scales.h" #include "parton.h" #include "npff.h" #include "string.h" #include "clock_real.h" #include #include #include //PDFs mellin moments at the factorisation scale complex *pdfevol::UVP; complex *pdfevol::DVP; complex *pdfevol::USP; complex *pdfevol::DSP; complex *pdfevol::SSP; complex *pdfevol::GLP; complex *pdfevol::CHP; complex *pdfevol::BOP; complex *pdfevol::fx1; complex *pdfevol::fx2; complex pdfevol::fn1[2*MAXNF+1]; complex pdfevol::fn2[2*MAXNF+1]; //scales complex pdfevol::bscale; complex pdfevol::bstarscale; complex pdfevol::bstartilde; complex pdfevol::qbstar; complex pdfevol::bcomplex; complex pdfevol::XL; complex pdfevol::XL1; complex pdfevol::SALP; complex pdfevol::alpr; using namespace parton; //fortran interface void pdfevol_(int& i1, int& i2, int& sign) { pdfevol::retrieve(i1-1, i2-1, sign-1); }; //moments at the starting scale void pdfevol::allocate() { UVP = new complex [mellinint::mdim]; DVP = new complex [mellinint::mdim]; USP = new complex [mellinint::mdim]; DSP = new complex [mellinint::mdim]; SSP = new complex [mellinint::mdim]; GLP = new complex [mellinint::mdim]; CHP = new complex [mellinint::mdim]; BOP = new complex [mellinint::mdim]; } void pdfevol::free() { delete[] UVP; delete[] DVP; delete[] USP; delete[] DSP; delete[] SSP; delete[] GLP; delete[] CHP; delete[] BOP; } //evolved moments void pdfevol::allocate_fx() { fx1 = new complex [mellinint::mdim*(2*MAXNF+1)*2]; fx2 = new complex [mellinint::mdim*(2*MAXNF+1)*2]; } void pdfevol::free_fx() { delete[] fx1; delete[] fx2; } void pdfevol::init() { //calculate Mellin moments of PDFs if (opts.fmufac == 0) - cout << "Initialise PDF moments with numerical integration... " << flush; + if (!opts.silent) cout << "Initialise PDF moments with numerical integration... " << flush; //double xmin = 1e-8; double xmin = pow(bins.mbins.front()/opts.sroot,2); //Restrict the integration of moments to xmin = m/sqrt(s)*exp(-ymax) = (m/sqrt(s))^2 mellinpdf::init(xmin); clock_t begin_time, end_time; //Old Fortran code for the moments /* fcomplex uval,dval,usea,dsea,splus,ssea,glu,charm,bot; begin_time = clock(); for (int k = 0; k < mellinint::mdim; k++) { int hadron = 1; //opts.ih1; fcomplex XN = fcx(mellinint::Np[k]); //compute positive branch only, the negative branch is obtained by complex conjugation double facscale = opts.kmufac*opts.rmass; pdfmoments_(hadron,facscale,XN,uval,dval,usea,dsea,splus,ssea,glu,charm,bot,xmin); // cout << "moment " << k << " " << cx(XN) << " "; // cout << "uval " << cx(uval) << endl; // cout << "dval " << dval << endl; // cout << "usea " << usea << endl; // cout << "dsea " << dsea << endl; // cout << "gluon " << cx(glu) << endl; // cout << "charm " << charm << endl; // cout << "bottom" << bot << endl; UVP[k] = cx(uval); DVP[k] = cx(dval); USP[k] = cx(usea); DSP[k] = cx(dsea); SSP[k] = cx(ssea);//SSP[k] = cx(splus); !! issue for PDFs with s-sbar asymmetry !! GLP[k] = cx(glu); CHP[k] = cx(charm); BOP[k] = cx(bot); } end_time = clock(); cout << "Done " << float(end_time - begin_time)/CLOCKS_PER_SEC << endl; */ /* //polynomial interpolation for analytical continuation int order = 500; complex a = opts.cpoint+1-2*opts.zmax*1i; complex b = opts.cpoint+1+2*opts.zmax*1i; complex c = 0.5*(a+b); complex m = 0.5*(b-a); complex f[order]; for (int i = 1; i <= order; i++) { complex x = c+m*cheb::xxx[order-1][i-1]; int hadron = 1; //opts.ih1; fcomplex XN = fcx(x); double facscale = 1.0;//opts.kmufac*opts.rmass; pdfmoments_(hadron,facscale,XN,uval,dval,usea,dsea,splus,ssea,glu,charm,bot); f[i-1] = cx(uval); } for (int i = 0; i < 100; i++) { complex x = a+(b-a)*double(i)/100.; int hadron = 1; //opts.ih1; fcomplex XN = fcx(x); double facscale = 1.0;//opts.kmufac*opts.rmass; pdfmoments_(hadron,facscale,XN,uval,dval,usea,dsea,splus,ssea,glu,charm,bot); cout << setw(30) << x << setw(30) << cx(uval) << setw(30) << cheb::ipol(a,b,order, f, x) << setw(30) << cx(uval)-cheb::ipol(a,b,order, f, x) << endl; } for (int i = 1; i <= order; i++) { complex x = c+m*cheb::xxx[order-1][i-1]; cout << x << " " << f[i-1] << " " << cheb::ipol(a,b,order, f, x) << endl; } //verify for (int k = 0; k < mellinint::mdim; k++) { complex z = mellinint::Np[k]; cout << setw(30) << z << setw(30) << UVP[k] << setw(30) << cheb::ipol(a,b,order, f, z) << endl; } */ if (opts.fmufac == 0) { allocate(); scales::set(opts.rmass); begin_time = clock(); update(); end_time = clock(); - cout << "Done in " << float(end_time - begin_time)/CLOCKS_PER_SEC*1000. << "ms" << endl; + if (!opts.silent) cout << "Done in " << float(end_time - begin_time)/CLOCKS_PER_SEC*1000. << "ms" << endl; } } +void pdfevol::release() +{ + if (opts.fmufac == 0) + free(); +} + void pdfevol::update() { clock_t begin_time, end_time; //Restrict the integration of moments to xmin = m/sqrt(s)*exp(-ymax) = (m/sqrt(s))^2 //double xmin = pow(phasepace::m/opts.sroot,2); //mellinpdf::init(xmin); //scales::set(phasespace::m); //assume scales were already set mellinpdf::allocate(); begin_time = clock(); mellinpdf::evalpdfs(scales::fac); if (opts.mellininv == 1 || opts.phi > 0.5) mellinpdf::laguerre_ipol(); else mellinpdf::gauss_quad(); end_time = clock(); //cout << "mll is " << scales::fac << " x to N done in " << float(end_time - begin_time)/CLOCKS_PER_SEC*1000. << "ms" << endl; for (int k = 0; k < mellinint::mdim; k++) { UVP[k] = mellinpdf::UV[k]; DVP[k] = mellinpdf::DV[k]; USP[k] = mellinpdf::US[k]; DSP[k] = mellinpdf::DS[k]; SSP[k] = mellinpdf::SM[k]; GLP[k] = mellinpdf::GL[k]; CHP[k] = mellinpdf::CP[k]; BOP[k] = mellinpdf::BP[k]; //cout << "moment " << k << " " << mellinint::Np[k] << " "; //cout << "uval " << mellinpdf::UV[k] << endl; //cout << "dval " << mellinpdf::DV[k] << endl; //cout << "usea " << mellinpdf::US[k] << endl; //cout << "dsea " << mellinpdf::DS[k] << endl; //cout << "ssea " << mellinpdf::SM[k] << endl; //cout << "gluon " << mellinpdf::GL[k] << endl; //cout << "charm " << mellinpdf::CP[k] << endl; //cout << "bottom" << mellinpdf::BP[k] << endl; } mellinpdf::free(); } // PROVIDES MOMENTS OF DENSITIES AT A GIVEN SCALE (INCLUDES EVOLUTION) // AND ANOMALOUS DIMENSIONS // EVERYTHING IN MELLIN SPACE // // input: I point in z grid, ISIGN (+ or -), IBEAM (1 or 2), SCALE2 (b), alps = alpqf (mass dependent) // output: FN, alpq = alps * alphasl(scale2) // dependence: FN(b, mass, I) // // *************************************** // Can completely cache the output FN in FN(I,IFIT,ISIG), and calculate in the init? No because of b // reno2 is cached and looped only on I, before entering the I1 I2 doube loop into cfx1 cfx2p cfx2m //Evolve the Mellin moment of PDF corresponding to the index i, sign sign, beam beam, from the scale q2 to the scale scale2(b) //Output in fx void pdfevol::evolution(int i) //from reno2 { // i is the index of the complex mellin moment in the z-space for the gaussian quadrature used for the mellin inversion //N flavour dependence int nf = resconst::NF; //At LL there is no PDF evolution, PDFs are evaluated at the factorisation scale if (opts.order == 0) { //XP[i] are moments of PDFs at the starting scale (factorisation scale) complex fx[11]; fx[0+MAXNF] = GLP[i]; fx[1+MAXNF] = UVP[i] + USP[i]; fx[-1+MAXNF] = USP[i]; fx[2+MAXNF] = DVP[i] + DSP[i]; fx[-2+MAXNF] = DSP[i]; fx[3+MAXNF] = SSP[i]; fx[-3+MAXNF] = SSP[i]; if (nf >= 4) { fx[4+MAXNF] = CHP[i]; fx[-4+MAXNF] = CHP[i]; } else { fx[4+MAXNF] = 0.; fx[-4+MAXNF] = 0.; } if (nf >= 5) { fx[5+MAXNF] = BOP[i]; fx[-5+MAXNF] = BOP[i]; } else { fx[5+MAXNF] = 0.; fx[-5+MAXNF] = 0.; } storemoments(i, fx); return; } complex alpq, ALPr; //Moments at the factorisation scale complex UVI, DVI, USI, DSI, SSI, GLI, CHI, BOI; //evolve only the moments of the positive branch, the negative branch is obtained by complex conjugation int sign = mesq::positive; //Moments of PDFs at the starting scale (factorisation scale) UVI = UVP[i]; DVI = DVP[i]; USI = USP[i]; DSI = DSP[i]; SSI = SSP[i]; GLI = GLP[i]; CHI = CHP[i]; BOI = BOP[i]; // *********************** // this part can be precomputed complex UVN = UVI; complex DVN = DVI; complex NS3N = UVI + 2.*USI - DVI - 2.*DSI; //(u+ub-d-db) u-d complex NS8N = UVI + 2.*USI + DVI + 2.*DSI - 4.*SSI; //(u+ub+d+db-s-sb) u+d-s complex GLN = GLI; complex SIN, NS15N, NS24N, NS35N; if (nf == 5) { SIN = UVI + DVI + 2.*USI + 2.*DSI + 2.*SSI + 2.*CHI + 2.*BOI; //(u+ub+d+db+s+sb+c+cb+b+bb) -> all quarks u+d+s+c+b NS15N = UVI + DVI + 2.*USI + 2.*DSI + 2.*SSI - 6.*CHI; //(u+ub+d+db+s+sb-3(c+cb)) u+d+s-3c NS24N = UVI + DVI + 2.*USI + 2.*DSI + 2.*SSI + 2.*CHI - 8.*BOI; //(u+ub+d+db+s+sb+c+cb-4(b+bb)) u+d+s+c-4b NS35N = SIN; } if (nf == 4) { SIN = UVI + DVI + 2.*USI + 2.*DSI + 2.*SSI + 2.*CHI; //(u+ub+d+db+s+sb+c+cb) -> all quarks NS15N = UVI + DVI + 2.*USI + 2.*DSI + 2.*SSI - 6.*CHI; NS24N = UVI + DVI + 2.*USI + 2.*DSI + 2.*SSI + 2.*CHI; NS35N = SIN; } if (nf == 3) { SIN = UVI + DVI + 2.*USI + 2.*DSI + 2.*SSI; //(u+ub+d+db+s+sb) -> all quarks NS15N = SIN; NS24N = SIN; NS35N = SIN; } complex SG = SIN; complex GL = GLN; // ************************************** // retrieved values cached in anomalous.C complex ANS = anomalous::ans[anomalous::index(i,sign)]; complex AM = anomalous::am[anomalous::index(i,sign)]; complex AP = anomalous::ap[anomalous::index(i,sign)]; complex AL = anomalous::al[anomalous::index(i,sign)]; complex BE = anomalous::be[anomalous::index(i,sign)]; complex AB = anomalous::ab[anomalous::index(i,sign)]; complex AC = 1. -AL; complex RMIN = anomalous::rmin[anomalous::index(i,sign)]; complex RPLUS = anomalous::rplus[anomalous::index(i,sign)]; complex RMMQQ = anomalous::RMMQQ[anomalous::index(i,sign)]; complex RMMQG = anomalous::RMMQG[anomalous::index(i,sign)]; complex RMMGQ = anomalous::RMMGQ[anomalous::index(i,sign)]; complex RMMGG = anomalous::RMMGG[anomalous::index(i,sign)]; complex RMPQQ = anomalous::RMPQQ[anomalous::index(i,sign)]; complex RMPQG = anomalous::RMPQG[anomalous::index(i,sign)]; complex RMPGQ = anomalous::RMPGQ[anomalous::index(i,sign)]; complex RMPGG = anomalous::RMPGG[anomalous::index(i,sign)]; complex RPMQQ = anomalous::RPMQQ[anomalous::index(i,sign)]; complex RPMQG = anomalous::RPMQG[anomalous::index(i,sign)]; complex RPMGQ = anomalous::RPMGQ[anomalous::index(i,sign)]; complex RPMGG = anomalous::RPMGG[anomalous::index(i,sign)]; complex RPPQQ = anomalous::RPPQQ[anomalous::index(i,sign)]; complex RPPQG = anomalous::RPPQG[anomalous::index(i,sign)]; complex RPPGQ = anomalous::RPPGQ[anomalous::index(i,sign)]; complex RPPGG = anomalous::RPPGG[anomalous::index(i,sign)]; // ************************************** // ************************************** // b-dependence //resummation scale // complex XL = 1./cx(alphasl_(fcx(scale2))); // complex XL1 = 1.- XL; // complex SALP = log(XL); //--> SALP ~ log[alphas(Q)/alphas(b0/b)] complex S = SALP; // cout << S << " " << < ENS = exp(-ANS*S); complex EM = exp(-AM*S); complex EP = exp(-AP*S); complex EMP = EM/EP; complex EPM = EP/EM; //...EVOLUTION OF LIGHT PARTON DENSITIES //double q2s = q2/pow(resint::a,2); //resummation scale //double alpqf = dyalphas_lhapdf_(sqrt(q2s))/4./M_PI; //alphas at the resummation scale //complex alpq = alpqf * alphasl(scale2); //alphas at the resummation scale times alphas at 1/b //complex alpr= alpq * 1 *(opts.order-1); //--> alpr = 0 at NLL; alpr = alphas(Q) * alphasl ~ alphas(b0/b) at NNLL UVN = UVN * ENS * (1.+ alpr * XL1 * RMIN); DVN = DVN * ENS * (1.+ alpr * XL1 * RMIN); NS3N = NS3N * ENS * (1.+ alpr * XL1 * RPLUS); NS8N = NS8N * ENS * (1.+ alpr * XL1 * RPLUS); SIN = EM * ((AL + alpr * (RMMQQ*XL1 + RMPQQ*(EPM-XL)))* SG + (BE + alpr * (RMMQG*XL1 + RMPQG*(EPM-XL))) * GL) + EP * ((AC + alpr * (RPPQQ*XL1 + RPMQQ*(EMP-XL)))* SG + (-BE + alpr * (RPPQG*XL1 + RPMQG*(EMP-XL))) * GL); GLN = EM * ((AB + alpr * (RMMGQ*XL1 + RMPGQ*(EPM-XL)))* SG + (AC + alpr * (RMMGG*XL1 + RMPGG*(EPM-XL))) * GL) + EP *((-AB + alpr * (RPPGQ*XL1 + RPMGQ*(EMP-XL)))* SG + (AL + alpr * (RPPGG*XL1 + RPMGG*(EMP-XL))) * GL); NS15N = NS15N * ENS * (1.+ alpr * XL1 * RPLUS); NS24N = NS24N * ENS * (1.+ alpr * XL1 * RPLUS); NS35N = SIN; //... FLAVOUR DECOMPOSITION OF THE QUARK SEA : complex SSN, DSN, USN, CHN, BON; SSN = (10.* SIN + 2.* NS35N + 3.* NS24N + 5.* NS15N - 20.* NS8N) / 120.; DSN = (10.* SIN + 2.* NS35N + 3.* NS24N + 5.* NS15N + 10.* NS8N - 30.* NS3N - 60.* DVN) / 120.; USN = (10.* SIN + 2.* NS35N + 3.* NS24N + 5.* NS15N + 10.* NS8N + 30.* NS3N - 60.* UVN) / 120.; CHN = (UVN + DVN + 2.*USN + 2.*DSN + 2.*SSN - NS15N)/6.; BON = (UVN + DVN + 2.*USN + 2.*DSN + 2.*SSN + 2.*CHN - NS24N)/8.; //equivalent to: //CHN = (10.* SIN + 2. *NS35N + 3.* NS24N - 15.* NS15N) / 120.; //BON = (10.* SIN + 2. *NS35N - 12.* NS24N) / 120.; if (nf == 3) //GRV { SSN= (20.* SIN - 20.* NS8N)/120.; DSN = (20.* SIN + 10.* NS8N - 30.* NS3N - 60.* DVN) / 120.; USN = (20.* SIN + 10.* NS8N + 30.* NS3N - 60.* UVN) / 120.; CHN=0.; BON=0.; } //if (fabs(bstarscale) < LHAPDF::getThreshold(4)) // CHN *= exp(-pow((LHAPDF::getThreshold(4)-fabs(bstarscale)),2)/pow((LHAPDF::getThreshold(4)/10.) ,2)); //=0 // double delta = 1./5.; // if (fabs(bstarscale) < LHAPDF::getThreshold(5)*(1+delta/2.)) // BON *= exp(-pow((LHAPDF::getThreshold(5)*(1+delta/2.)-fabs(bstarscale)),2)/pow((LHAPDF::getThreshold(5)*delta),2)); //=0 // ************************************** // output: // bbar cbar sbar dbar ubar gluon u d s c b // -5 -4 -3 -2 -1 0 1 2 3 4 5 complex fx[11]; fx[0+MAXNF] = GLN; fx[1+MAXNF] = UVN + USN; fx[-1+MAXNF] = USN; fx[2+MAXNF] = DVN + DSN; fx[-2+MAXNF] = DSN; fx[3+MAXNF] = SSN; fx[-3+MAXNF] = SSN; if (nf >= 4) { fx[4+MAXNF] = CHN; fx[-4+MAXNF] = CHN; } else { fx[4+MAXNF] = 0.; fx[-4+MAXNF] = 0.; } if (nf >= 5) { fx[5+MAXNF] = BON; fx[-5+MAXNF] = BON; } else { fx[5+MAXNF] = 0.; fx[-5+MAXNF] = 0.; } storemoments(i, fx); } //Old fortran code void pdfevol::calculate(int i) { //N flavour dependence int nf = resconst::NF; int hadron = 1; //double facscale = fabs(bscale); //double facscale = fabs(bstarscale); //double facscale = fabs(opts.muf); double facscale = fabs(pdfevol::bstartilde); //bstartilde = qbstar * resint::mures / sqrt(pow(qbstar,2) + resint::mures2); fcomplex XN = fcx(mellinint::Np[i]); double xmin = 1e-8; complex fx[11]; fcomplex uval,dval,usea,dsea,s,sbar,glu,charm,bot; pdfmoments_(hadron,facscale,XN,uval,dval,usea,dsea,s,sbar,glu,charm,bot,xmin); fx[0+MAXNF] = cx(glu); fx[1+MAXNF] = cx(uval) + cx(usea); fx[-1+MAXNF] = cx(usea); fx[2+MAXNF] = cx(dval) + cx(dsea); fx[-2+MAXNF] = cx(dsea); fx[3+MAXNF] = cx(s); fx[-3+MAXNF] = cx(sbar); if (nf >= 4) { fx[4+MAXNF] = cx(charm); fx[-4+MAXNF] = cx(charm); } else { fx[4+MAXNF] = 0.; fx[-4+MAXNF] = 0.; } if (nf >= 5) { fx[5+MAXNF] = cx(bot); fx[-5+MAXNF] = cx(bot); } else { fx[5+MAXNF] = 0.; fx[-5+MAXNF] = 0.; } storemoments(i, fx); } void pdfevol::calculate() { clock_t begin_time, end_time; //double facscale = fabs(bscale); //double facscale = fabs(bstarscale); //double facscale = fabs(opts.muf); double facscale = fabs(pdfevol::bstartilde); //bstartilde = qbstar * resint::mures / sqrt(pow(qbstar,2) + resint::mures2); //cout << facscale << endl; complex fx[11]; mellinpdf::allocate(); begin_time = clock(); mellinpdf::evalpdfs(facscale); if (opts.mellininv == 1 || opts.phi > 0.5) mellinpdf::laguerre_ipol(); else mellinpdf::gauss_quad(); end_time = clock(); //cout << "facscale is " << facscale << " x to N done in " << float(end_time - begin_time)/CLOCKS_PER_SEC*1000. << "ms" << endl; for (int k = 0; k < mellinint::mdim; k++) { fx[g] = mellinpdf::GL[k]; fx[u] = mellinpdf::UV[k]+mellinpdf::US[k]; fx[ub] = mellinpdf::US[k]; fx[d] = mellinpdf::DV[k]+mellinpdf::DS[k]; fx[db] = mellinpdf::DS[k]; fx[s] = mellinpdf::SP[k]; fx[sb] = mellinpdf::SM[k]; if (resconst::NF >= 4) { fx[c] = mellinpdf::CP[k]; fx[cb] = mellinpdf::CM[k]; } else { fx[c] = 0.; fx[cb] = 0.; } if (resconst::NF >= 5) { fx[b] = mellinpdf::BP[k]; fx[bb] = mellinpdf::BM[k]; } else { fx[b] = 0.; fx[bb] = 0.; } //cout << k << " " << fx[g] << endl; storemoments(k, fx); } mellinpdf::free(); } void pdfevol::storemoments(int i, complex fx[11]) { //Save the evolved PDFs into the fx1 and fx2 arrays int negidx = mellinint::mdim*11; int nf = 2*MAXNF+1; //beam 1 positive fx1[i*nf+bb] = fx[bb]; fx1[i*nf+cb] = fx[cb]; fx1[i*nf+sb] = fx[sb]; fx1[i*nf+g ] = fx[g ]; fx1[i*nf+s ] = fx[s ]; fx1[i*nf+c ] = fx[c ]; fx1[i*nf+b ] = fx[b ]; if (opts.ih1 == 1) { fx1[i*nf+db] = fx[db]; fx1[i*nf+ub] = fx[ub]; fx1[i*nf+u ] = fx[u ]; fx1[i*nf+d ] = fx[d ]; } else if (opts.ih1 == -1) { fx1[i*nf+db] = fx[d ]; fx1[i*nf+ub] = fx[u ]; fx1[i*nf+u ] = fx[ub]; fx1[i*nf+d ] = fx[db]; } //beam 1 negative (never used) fx1[negidx+i*nf+bb] = conj(fx[bb]); fx1[negidx+i*nf+cb] = conj(fx[cb]); fx1[negidx+i*nf+sb] = conj(fx[sb]); fx1[negidx+i*nf+g ] = conj(fx[g ]); fx1[negidx+i*nf+s ] = conj(fx[s ]); fx1[negidx+i*nf+c ] = conj(fx[c ]); fx1[negidx+i*nf+b ] = conj(fx[b ]); if (opts.ih1 == 1) { fx1[negidx+i*nf+db] = conj(fx[db]); fx1[negidx+i*nf+ub] = conj(fx[ub]); fx1[negidx+i*nf+u ] = conj(fx[u ]); fx1[negidx+i*nf+d ] = conj(fx[d ]); } else if (opts.ih1 == -1) { fx1[negidx+i*nf+db] = conj(fx[d ]); fx1[negidx+i*nf+ub] = conj(fx[u ]); fx1[negidx+i*nf+u ] = conj(fx[ub]); fx1[negidx+i*nf+d ] = conj(fx[db]); } //beam 2 positive fx2[i*nf+bb] = fx[bb]; fx2[i*nf+cb] = fx[cb]; fx2[i*nf+sb] = fx[sb]; fx2[i*nf+g ] = fx[g ]; fx2[i*nf+s ] = fx[s ]; fx2[i*nf+c ] = fx[c ]; fx2[i*nf+b ] = fx[b ]; if (opts.ih2 == 1) { fx2[i*nf+db] = fx[db]; fx2[i*nf+ub] = fx[ub]; fx2[i*nf+u ] = fx[u ]; fx2[i*nf+d ] = fx[d ]; } else if (opts.ih2 == -1) { fx2[i*nf+db] = fx[d ]; fx2[i*nf+ub] = fx[u ]; fx2[i*nf+u ] = fx[ub]; fx2[i*nf+d ] = fx[db]; } //beam 2 negative fx2[negidx+i*nf+bb] = conj(fx[bb]); fx2[negidx+i*nf+cb] = conj(fx[cb]); fx2[negidx+i*nf+sb] = conj(fx[sb]); fx2[negidx+i*nf+g ] = conj(fx[g ]); fx2[negidx+i*nf+s ] = conj(fx[s ]); fx2[negidx+i*nf+c ] = conj(fx[c ]); fx2[negidx+i*nf+b ] = conj(fx[b ]); if (opts.ih2 == 1) { fx2[negidx+i*nf+db] = conj(fx[db]); fx2[negidx+i*nf+ub] = conj(fx[ub]); fx2[negidx+i*nf+u ] = conj(fx[u ]); fx2[negidx+i*nf+d ] = conj(fx[d ]); } else if (opts.ih2 == -1) { fx2[negidx+i*nf+db] = conj(fx[d ]); fx2[negidx+i*nf+ub] = conj(fx[u ]); fx2[negidx+i*nf+u ] = conj(fx[ub]); fx2[negidx+i*nf+d ] = conj(fx[db]); } } void pdfevol::storemoments_fortran(int i, complex fx[11]) { //Save the evolved PDFs into the fortran common block //beam 1 creno_.cfx1_[i][-5+MAXNF] = fcx(fx[-5+MAXNF]); creno_.cfx1_[i][-4+MAXNF] = fcx(fx[-4+MAXNF]); creno_.cfx1_[i][-3+MAXNF] = fcx(fx[-3+MAXNF]); creno_.cfx1_[i][ 0+MAXNF] = fcx(fx[ 0+MAXNF]); creno_.cfx1_[i][ 3+MAXNF] = fcx(fx[ 3+MAXNF]); creno_.cfx1_[i][ 4+MAXNF] = fcx(fx[ 4+MAXNF]); creno_.cfx1_[i][ 5+MAXNF] = fcx(fx[ 5+MAXNF]); if (opts.ih1 == 1) { creno_.cfx1_[i][-2+MAXNF] = fcx(fx[-2+MAXNF]); creno_.cfx1_[i][-1+MAXNF] = fcx(fx[-1+MAXNF]); creno_.cfx1_[i][ 1+MAXNF] = fcx(fx[ 1+MAXNF]); creno_.cfx1_[i][ 2+MAXNF] = fcx(fx[ 2+MAXNF]); } else if (opts.ih1 == -1) { creno_.cfx1_[i][-2+MAXNF] = fcx(fx[ 2+MAXNF]); creno_.cfx1_[i][-1+MAXNF] = fcx(fx[ 1+MAXNF]); creno_.cfx1_[i][ 1+MAXNF] = fcx(fx[-1+MAXNF]); creno_.cfx1_[i][ 2+MAXNF] = fcx(fx[-2+MAXNF]); } //beam 2 positive creno_.cfx2p_[i][-5+MAXNF] = fcx(fx[-5+MAXNF]); creno_.cfx2p_[i][-4+MAXNF] = fcx(fx[-4+MAXNF]); creno_.cfx2p_[i][-3+MAXNF] = fcx(fx[-3+MAXNF]); creno_.cfx2p_[i][ 0+MAXNF] = fcx(fx[ 0+MAXNF]); creno_.cfx2p_[i][ 3+MAXNF] = fcx(fx[ 3+MAXNF]); creno_.cfx2p_[i][ 4+MAXNF] = fcx(fx[ 4+MAXNF]); creno_.cfx2p_[i][ 5+MAXNF] = fcx(fx[ 5+MAXNF]); if (opts.ih2 == 1) { creno_.cfx2p_[i][-2+MAXNF] = fcx(fx[-2+MAXNF]); creno_.cfx2p_[i][-1+MAXNF] = fcx(fx[-1+MAXNF]); creno_.cfx2p_[i][ 1+MAXNF] = fcx(fx[ 1+MAXNF]); creno_.cfx2p_[i][ 2+MAXNF] = fcx(fx[ 2+MAXNF]); } else if (opts.ih2 == -1) { creno_.cfx2p_[i][-2+MAXNF] = fcx(fx[ 2+MAXNF]); creno_.cfx2p_[i][-1+MAXNF] = fcx(fx[ 1+MAXNF]); creno_.cfx2p_[i][ 1+MAXNF] = fcx(fx[-1+MAXNF]); creno_.cfx2p_[i][ 2+MAXNF] = fcx(fx[-2+MAXNF]); } //beam 2 negative creno_.cfx2m_[i][-5+MAXNF] = fcx(conj(fx[-5+MAXNF])); creno_.cfx2m_[i][-4+MAXNF] = fcx(conj(fx[-4+MAXNF])); creno_.cfx2m_[i][-3+MAXNF] = fcx(conj(fx[-3+MAXNF])); creno_.cfx2m_[i][ 0+MAXNF] = fcx(conj(fx[ 0+MAXNF])); creno_.cfx2m_[i][ 3+MAXNF] = fcx(conj(fx[ 3+MAXNF])); creno_.cfx2m_[i][ 4+MAXNF] = fcx(conj(fx[ 4+MAXNF])); creno_.cfx2m_[i][ 5+MAXNF] = fcx(conj(fx[ 5+MAXNF])); if (opts.ih2 == 1) { creno_.cfx2m_[i][-2+MAXNF] = fcx(conj(fx[-2+MAXNF])); creno_.cfx2m_[i][-1+MAXNF] = fcx(conj(fx[-1+MAXNF])); creno_.cfx2m_[i][ 1+MAXNF] = fcx(conj(fx[ 1+MAXNF])); creno_.cfx2m_[i][ 2+MAXNF] = fcx(conj(fx[ 2+MAXNF])); } else if (opts.ih2 == -1) { creno_.cfx2m_[i][-2+MAXNF] = fcx(conj(fx[ 2+MAXNF])); creno_.cfx2m_[i][-1+MAXNF] = fcx(conj(fx[ 1+MAXNF])); creno_.cfx2m_[i][ 1+MAXNF] = fcx(conj(fx[-1+MAXNF])); creno_.cfx2m_[i][ 2+MAXNF] = fcx(conj(fx[-2+MAXNF])); } } //Apply the flavour dependent form factors void pdfevol::flavour_kt() { int negidx = mellinint::mdim*11; int nf = 2*MAXNF+1; complex uv, dv, us, ds; for (int i = 0; i < mellinint::mdim; i++) { //beam 1 positive fx1[i*nf+bb] *= npff::boff; fx1[i*nf+cb] *= npff::chff; fx1[i*nf+sb] *= npff::ssff; fx1[i*nf+g ] *= npff::glff; fx1[i*nf+s ] *= npff::ssff; fx1[i*nf+c ] *= npff::chff; fx1[i*nf+b ] *= npff::boff; if (opts.ih1 == 1) { uv = (fx1[i*nf+u] - fx1[i*nf+ub]); dv = (fx1[i*nf+d] - fx1[i*nf+db]); us = fx1[i*nf+ub]; ds = fx1[i*nf+db]; fx1[i*nf+u] = uv * npff::uvff + us * npff::usff; fx1[i*nf+d] = dv * npff::dvff + ds * npff::dsff; fx1[i*nf+ub] = us * npff::usff; fx1[i*nf+db] = ds * npff::dsff; } else if (opts.ih1 == -1) { uv = (fx1[i*nf+ub] - fx1[i*nf+u]); dv = (fx1[i*nf+db] - fx1[i*nf+d]); us = fx1[i*nf+u]; ds = fx1[i*nf+d]; fx1[i*nf+ub] = uv * npff::uvff + us * npff::usff; fx1[i*nf+db] = dv * npff::dvff + ds * npff::dsff; fx1[i*nf+u] = us * npff::usff; fx1[i*nf+d] = ds * npff::dsff; } //beam 2 positive fx2[i*nf+bb] *= npff::boff; fx2[i*nf+cb] *= npff::chff; fx2[i*nf+sb] *= npff::ssff; fx2[i*nf+g ] *= npff::glff; fx2[i*nf+s ] *= npff::ssff; fx2[i*nf+c ] *= npff::chff; fx2[i*nf+b ] *= npff::boff; if (opts.ih2 == 1) { uv = (fx2[i*nf+u] - fx2[i*nf+ub]); dv = (fx2[i*nf+d] - fx2[i*nf+db]); us = fx2[i*nf+ub]; ds = fx2[i*nf+db]; fx2[i*nf+u] = uv * npff::uvff + us * npff::usff; fx2[i*nf+d] = dv * npff::dvff + ds * npff::dsff; fx2[i*nf+ub] = us * npff::usff; fx2[i*nf+db] = ds * npff::dsff; } else if (opts.ih2 == -1) { uv = (fx2[i*nf+ub] - fx2[i*nf+u]); dv = (fx2[i*nf+db] - fx2[i*nf+d]); us = fx2[i*nf+u]; ds = fx2[i*nf+d]; fx2[i*nf+ub] = uv * npff::uvff + us * npff::usff; fx2[i*nf+db] = dv * npff::dvff + ds * npff::dsff; fx2[i*nf+u] = us * npff::usff; fx2[i*nf+d] = ds * npff::dsff; } } } void pdfevol::retrieve(int i1, int i2, int sign) { int nf = 2*MAXNF+1; int negidx = mellinint::mdim*nf; fn1[bb] = fx1[i1*nf+bb]; fn1[cb] = fx1[i1*nf+cb]; fn1[sb] = fx1[i1*nf+sb]; fn1[db] = fx1[i1*nf+db]; fn1[ub] = fx1[i1*nf+ub]; fn1[g ] = fx1[i1*nf+g ]; fn1[u ] = fx1[i1*nf+u ]; fn1[d ] = fx1[i1*nf+d ]; fn1[s ] = fx1[i1*nf+s ]; fn1[c ] = fx1[i1*nf+c ]; fn1[b ] = fx1[i1*nf+b ]; if (sign == mesq::positive) { fn2[bb] = fx2[i2*nf+bb]; fn2[cb] = fx2[i2*nf+cb]; fn2[sb] = fx2[i2*nf+sb]; fn2[db] = fx2[i2*nf+db]; fn2[ub] = fx2[i2*nf+ub]; fn2[g ] = fx2[i2*nf+g ]; fn2[u ] = fx2[i2*nf+u ]; fn2[d ] = fx2[i2*nf+d ]; fn2[s ] = fx2[i2*nf+s ]; fn2[c ] = fx2[i2*nf+c ]; fn2[b ] = fx2[i2*nf+b ]; } else if (sign == mesq::negative) { fn2[bb] = fx2[negidx+i2*nf+bb]; fn2[cb] = fx2[negidx+i2*nf+cb]; fn2[sb] = fx2[negidx+i2*nf+sb]; fn2[db] = fx2[negidx+i2*nf+db]; fn2[ub] = fx2[negidx+i2*nf+ub]; fn2[g ] = fx2[negidx+i2*nf+g ]; fn2[u ] = fx2[negidx+i2*nf+u ]; fn2[d ] = fx2[negidx+i2*nf+d ]; fn2[s ] = fx2[negidx+i2*nf+s ]; fn2[c ] = fx2[negidx+i2*nf+c ]; fn2[b ] = fx2[negidx+i2*nf+b ]; } } void pdfevol::retrieve_fortran(int i1, int i2, int sign) { // cout << i1 << endl; // cout << creno_.cfx1_[i1][5].real << " " << creno_.cfx1_[i1][5].imag << endl; fn1[-5+MAXNF] = cx(creno_.cfx1_[i1][-5+MAXNF]); fn1[-4+MAXNF] = cx(creno_.cfx1_[i1][-4+MAXNF]); fn1[-3+MAXNF] = cx(creno_.cfx1_[i1][-3+MAXNF]); fn1[-2+MAXNF] = cx(creno_.cfx1_[i1][-2+MAXNF]); fn1[-1+MAXNF] = cx(creno_.cfx1_[i1][-1+MAXNF]); fn1[ 0+MAXNF] = cx(creno_.cfx1_[i1][ 0+MAXNF]); fn1[ 1+MAXNF] = cx(creno_.cfx1_[i1][ 1+MAXNF]); fn1[ 2+MAXNF] = cx(creno_.cfx1_[i1][ 2+MAXNF]); fn1[ 3+MAXNF] = cx(creno_.cfx1_[i1][ 3+MAXNF]); fn1[ 4+MAXNF] = cx(creno_.cfx1_[i1][ 4+MAXNF]); fn1[ 5+MAXNF] = cx(creno_.cfx1_[i1][ 5+MAXNF]); if (sign == mesq::positive) { fn2[-5+MAXNF] = cx(creno_.cfx2p_[i2][-5+MAXNF]); fn2[-4+MAXNF] = cx(creno_.cfx2p_[i2][-4+MAXNF]); fn2[-3+MAXNF] = cx(creno_.cfx2p_[i2][-3+MAXNF]); fn2[-2+MAXNF] = cx(creno_.cfx2p_[i2][-2+MAXNF]); fn2[-1+MAXNF] = cx(creno_.cfx2p_[i2][-1+MAXNF]); fn2[ 0+MAXNF] = cx(creno_.cfx2p_[i2][ 0+MAXNF]); fn2[ 1+MAXNF] = cx(creno_.cfx2p_[i2][ 1+MAXNF]); fn2[ 2+MAXNF] = cx(creno_.cfx2p_[i2][ 2+MAXNF]); fn2[ 3+MAXNF] = cx(creno_.cfx2p_[i2][ 3+MAXNF]); fn2[ 4+MAXNF] = cx(creno_.cfx2p_[i2][ 4+MAXNF]); fn2[ 5+MAXNF] = cx(creno_.cfx2p_[i2][ 5+MAXNF]); } else if (sign == mesq::negative) { fn2[-5+MAXNF] = cx(creno_.cfx2m_[i2][-5+MAXNF]); fn2[-4+MAXNF] = cx(creno_.cfx2m_[i2][-4+MAXNF]); fn2[-3+MAXNF] = cx(creno_.cfx2m_[i2][-3+MAXNF]); fn2[-2+MAXNF] = cx(creno_.cfx2m_[i2][-2+MAXNF]); fn2[-1+MAXNF] = cx(creno_.cfx2m_[i2][-1+MAXNF]); fn2[ 0+MAXNF] = cx(creno_.cfx2m_[i2][ 0+MAXNF]); fn2[ 1+MAXNF] = cx(creno_.cfx2m_[i2][ 1+MAXNF]); fn2[ 2+MAXNF] = cx(creno_.cfx2m_[i2][ 2+MAXNF]); fn2[ 3+MAXNF] = cx(creno_.cfx2m_[i2][ 3+MAXNF]); fn2[ 4+MAXNF] = cx(creno_.cfx2m_[i2][ 4+MAXNF]); fn2[ 5+MAXNF] = cx(creno_.cfx2m_[i2][ 5+MAXNF]); } } void pdfevol::retrieve_beam1(int i1) { int nf = 2*MAXNF+1; memcpy(fn1, &(fx1[i1*nf]), nf*sizeof(complex)); } void pdfevol::retrieve_beam2_pos(int i2) { int nf = 2*MAXNF+1; memcpy(fn2, &(fx2[i2*nf]), nf*sizeof(complex)); } void pdfevol::retrieve_beam2_neg() { fn2[bb] = conj(fn2[bb]); fn2[cb] = conj(fn2[cb]); fn2[sb] = conj(fn2[sb]); fn2[db] = conj(fn2[db]); fn2[ub] = conj(fn2[ub]); fn2[g ] = conj(fn2[g ]); fn2[u ] = conj(fn2[u ]); fn2[d ] = conj(fn2[d ]); fn2[s ] = conj(fn2[s ]); fn2[c ] = conj(fn2[c ]); fn2[b ] = conj(fn2[b ]); } void pdfevol::retrieve1d(int i, int sign) { int nf = 2*MAXNF+1; int negidx = mellinint::mdim*nf; if (sign == mesq::positive) { fn1[bb] = fx1[i*nf+bb]; fn1[cb] = fx1[i*nf+cb]; fn1[sb] = fx1[i*nf+sb]; fn1[db] = fx1[i*nf+db]; fn1[ub] = fx1[i*nf+ub]; fn1[g ] = fx1[i*nf+g ]; fn1[u ] = fx1[i*nf+u ]; fn1[d ] = fx1[i*nf+d ]; fn1[s ] = fx1[i*nf+s ]; fn1[c ] = fx1[i*nf+c ]; fn1[b ] = fx1[i*nf+b ]; } else if (sign == mesq::negative) { fn1[bb] = fx1[negidx+i*nf+bb]; fn1[cb] = fx1[negidx+i*nf+cb]; fn1[sb] = fx1[negidx+i*nf+sb]; fn1[db] = fx1[negidx+i*nf+db]; fn1[ub] = fx1[negidx+i*nf+ub]; fn1[g ] = fx1[negidx+i*nf+g ]; fn1[u ] = fx1[negidx+i*nf+u ]; fn1[d ] = fx1[negidx+i*nf+d ]; fn1[s ] = fx1[negidx+i*nf+s ]; fn1[c ] = fx1[negidx+i*nf+c ]; fn1[b ] = fx1[negidx+i*nf+b ]; } if (sign == mesq::positive) { fn2[bb] = fx2[i*nf+bb]; fn2[cb] = fx2[i*nf+cb]; fn2[sb] = fx2[i*nf+sb]; fn2[db] = fx2[i*nf+db]; fn2[ub] = fx2[i*nf+ub]; fn2[g ] = fx2[i*nf+g ]; fn2[u ] = fx2[i*nf+u ]; fn2[d ] = fx2[i*nf+d ]; fn2[s ] = fx2[i*nf+s ]; fn2[c ] = fx2[i*nf+c ]; fn2[b ] = fx2[i*nf+b ]; } else if (sign == mesq::negative) { fn2[bb] = fx2[negidx+i*nf+bb]; fn2[cb] = fx2[negidx+i*nf+cb]; fn2[sb] = fx2[negidx+i*nf+sb]; fn2[db] = fx2[negidx+i*nf+db]; fn2[ub] = fx2[negidx+i*nf+ub]; fn2[g ] = fx2[negidx+i*nf+g ]; fn2[u ] = fx2[negidx+i*nf+u ]; fn2[d ] = fx2[negidx+i*nf+d ]; fn2[s ] = fx2[negidx+i*nf+s ]; fn2[c ] = fx2[negidx+i*nf+c ]; fn2[b ] = fx2[negidx+i*nf+b ]; } } void pdfevol::retrieve1d_fortran(int i, int sign) { //cout << i << endl; //cout << creno_.cfx1_[i][5].real << " " << creno_.cfx1_[i][5].imag << endl; if (sign == mesq::positive) { fn1[-5+MAXNF] = cx(creno_.cfx1_[i][-5+MAXNF]); fn1[-4+MAXNF] = cx(creno_.cfx1_[i][-4+MAXNF]); fn1[-3+MAXNF] = cx(creno_.cfx1_[i][-3+MAXNF]); fn1[-2+MAXNF] = cx(creno_.cfx1_[i][-2+MAXNF]); fn1[-1+MAXNF] = cx(creno_.cfx1_[i][-1+MAXNF]); fn1[ 0+MAXNF] = cx(creno_.cfx1_[i][ 0+MAXNF]); fn1[ 1+MAXNF] = cx(creno_.cfx1_[i][ 1+MAXNF]); fn1[ 2+MAXNF] = cx(creno_.cfx1_[i][ 2+MAXNF]); fn1[ 3+MAXNF] = cx(creno_.cfx1_[i][ 3+MAXNF]); fn1[ 4+MAXNF] = cx(creno_.cfx1_[i][ 4+MAXNF]); fn1[ 5+MAXNF] = cx(creno_.cfx1_[i][ 5+MAXNF]); } else if (sign == mesq::negative) { fn1[-5+MAXNF] = conj(cx(creno_.cfx1_[i][-5+MAXNF])); fn1[-4+MAXNF] = conj(cx(creno_.cfx1_[i][-4+MAXNF])); fn1[-3+MAXNF] = conj(cx(creno_.cfx1_[i][-3+MAXNF])); fn1[-2+MAXNF] = conj(cx(creno_.cfx1_[i][-2+MAXNF])); fn1[-1+MAXNF] = conj(cx(creno_.cfx1_[i][-1+MAXNF])); fn1[ 0+MAXNF] = conj(cx(creno_.cfx1_[i][ 0+MAXNF])); fn1[ 1+MAXNF] = conj(cx(creno_.cfx1_[i][ 1+MAXNF])); fn1[ 2+MAXNF] = conj(cx(creno_.cfx1_[i][ 2+MAXNF])); fn1[ 3+MAXNF] = conj(cx(creno_.cfx1_[i][ 3+MAXNF])); fn1[ 4+MAXNF] = conj(cx(creno_.cfx1_[i][ 4+MAXNF])); fn1[ 5+MAXNF] = conj(cx(creno_.cfx1_[i][ 5+MAXNF])); } if (sign == mesq::positive) { fn2[-5+MAXNF] = cx(creno_.cfx2p_[i][-5+MAXNF]); fn2[-4+MAXNF] = cx(creno_.cfx2p_[i][-4+MAXNF]); fn2[-3+MAXNF] = cx(creno_.cfx2p_[i][-3+MAXNF]); fn2[-2+MAXNF] = cx(creno_.cfx2p_[i][-2+MAXNF]); fn2[-1+MAXNF] = cx(creno_.cfx2p_[i][-1+MAXNF]); fn2[ 0+MAXNF] = cx(creno_.cfx2p_[i][ 0+MAXNF]); fn2[ 1+MAXNF] = cx(creno_.cfx2p_[i][ 1+MAXNF]); fn2[ 2+MAXNF] = cx(creno_.cfx2p_[i][ 2+MAXNF]); fn2[ 3+MAXNF] = cx(creno_.cfx2p_[i][ 3+MAXNF]); fn2[ 4+MAXNF] = cx(creno_.cfx2p_[i][ 4+MAXNF]); fn2[ 5+MAXNF] = cx(creno_.cfx2p_[i][ 5+MAXNF]); } else if (sign == mesq::negative) { fn2[-5+MAXNF] = cx(creno_.cfx2m_[i][-5+MAXNF]); fn2[-4+MAXNF] = cx(creno_.cfx2m_[i][-4+MAXNF]); fn2[-3+MAXNF] = cx(creno_.cfx2m_[i][-3+MAXNF]); fn2[-2+MAXNF] = cx(creno_.cfx2m_[i][-2+MAXNF]); fn2[-1+MAXNF] = cx(creno_.cfx2m_[i][-1+MAXNF]); fn2[ 0+MAXNF] = cx(creno_.cfx2m_[i][ 0+MAXNF]); fn2[ 1+MAXNF] = cx(creno_.cfx2m_[i][ 1+MAXNF]); fn2[ 2+MAXNF] = cx(creno_.cfx2m_[i][ 2+MAXNF]); fn2[ 3+MAXNF] = cx(creno_.cfx2m_[i][ 3+MAXNF]); fn2[ 4+MAXNF] = cx(creno_.cfx2m_[i][ 4+MAXNF]); fn2[ 5+MAXNF] = cx(creno_.cfx2m_[i][ 5+MAXNF]); } } //Retrieve PDFs at the starting scale (muf) void pdfevol::retrievemuf(int i, int sign) { // i is the index of the complex mellin moment in the z-space for the gaussian quadrature used for the mellin inversion //N flavour dependence int nf = resconst::NF; //XP[i] are moments of PDFs at the starting scale (factorisation scale) complex fx[11]; fx[0+MAXNF] = GLP[i]; fx[1+MAXNF] = UVP[i] + USP[i]; fx[-1+MAXNF] = USP[i]; fx[2+MAXNF] = DVP[i] + DSP[i]; fx[-2+MAXNF] = DSP[i]; fx[3+MAXNF] = SSP[i]; fx[-3+MAXNF] = SSP[i]; if (nf >= 4) { fx[4+MAXNF] = CHP[i]; fx[-4+MAXNF] = CHP[i]; } else { fx[4+MAXNF] = 0.; fx[-4+MAXNF] = 0.; } if (nf >= 5) { fx[5+MAXNF] = BOP[i]; fx[-5+MAXNF] = BOP[i]; } else { fx[5+MAXNF] = 0.; fx[-5+MAXNF] = 0.; } storemoments(i, fx); retrieve1d(i, sign); // cout << i << " " << GLP[i] << " " << fx[0+MAXNF] << " " << fn1[MAXNF] << " " << fn2[MAXNF] << endl; return; } void pdfevol::truncate() { //Calculate truncated moments double x1 = phasespace::m/opts.sroot*exp(phasespace::ymin); double x2 = phasespace::m/opts.sroot*exp(-phasespace::ymax); //double x1 = 1e-8;//pow(phasespace::m/opts.sroot,2); //double x2 = 1e-8;//pow(phasespace::m/opts.sroot,2); double lx1 = log(x1); double lx2 = log(x2); //truncated moments (output) complex fx1[mellinint::mdim][2*MAXNF+1] = {0.}; complex fx2[mellinint::mdim][2*MAXNF+1] = {0.}; //cache x^(N) values complex x1n[mellinint::mdim]; complex x2n[mellinint::mdim]; for (int n = 0; n < mellinint::mdim; n++) { x1n[n] = pow(x1,mellinint::Np[n]); x2n[n] = pow(x2,mellinint::Np[n]); } //Normalisation times Jacobian complex facp = mellinint::CCp/2./M_PI/complex (0.,1); complex facm = mellinint::CCm/2./M_PI/complex (0.,1); //original moments times prefactor and weight complex fm1p[mellinint::mdim][2*MAXNF+1]; complex fm2p[mellinint::mdim][2*MAXNF+1]; complex fm1m[mellinint::mdim][2*MAXNF+1]; complex fm2m[mellinint::mdim][2*MAXNF+1]; for (int m = 0; m < mellinint::mdim; m++) for (int f = 0; f < 2*MAXNF+1; f++) { fm1p[m][f] = facp * cx(creno_.cfx1_[m][f] ) * mellinint::wn[m]; fm2p[m][f] = facp * cx(creno_.cfx2p_[m][f]) * mellinint::wn[m]; fm1m[m][f] = facm * conj(cx(creno_.cfx1_[m][f]) ) * mellinint::wn[m]; fm2m[m][f] = facm * conj(cx(creno_.cfx2p_[m][f])) * mellinint::wn[m]; } //cache factor (1-x^(N-M))/(N-M) which limit is ln(x) when N-M -> 0 complex llx1p[mellinint::mdim][mellinint::mdim]; complex llx2p[mellinint::mdim][mellinint::mdim]; complex llx1m[mellinint::mdim][mellinint::mdim]; complex llx2m[mellinint::mdim][mellinint::mdim]; for (int n = 0; n < mellinint::mdim; n++) for (int m = 0; m < mellinint::mdim; m++) { llx1p[n][m] = (1.-x1n[n]/x1n[m])/(mellinint::Np[n]-mellinint::Np[m]); llx2p[n][m] = (1.-x2n[n]/x2n[m])/(mellinint::Np[n]-mellinint::Np[m]); llx1m[n][m] = (1.-x1n[n]/conj(x1n[m]))/(mellinint::Np[n]-mellinint::Nm[m]); llx2m[n][m] = (1.-x2n[n]/conj(x2n[m]))/(mellinint::Np[n]-mellinint::Nm[m]); } //overwrite divergent diagonal part for (int n = 0; n < mellinint::mdim; n++) { llx1p[n][n] = -lx1; llx2p[n][n] = -lx2; } for (int n = 0; n < mellinint::mdim; n++) { //positive branch for (int m = 0; m < mellinint::mdim; m++) for (int f = 0; f < 2*MAXNF+1; f++) { /* if (m == n) { fx1[n][f] += fm1p[m][f] * (-lx1); fx2[n][f] += fm2p[m][f] * (-lx2); } else { fx1[n][f] += fm1p[m][f] * (1.-x1n[n]/x1n[m])/(mellinint::Np[n]-mellinint::Np[m]); fx2[n][f] += fm2p[m][f] * (1.-x2n[n]/x2n[m])/(mellinint::Np[n]-mellinint::Np[m]); } */ // fx1[n][f] += fm1p[m][f]*llx1p[n][m]; // fx2[n][f] += fm2p[m][f]*llx2p[n][m]; fx1[n][f] += fm1p[m][f]*llx1p[n][m] - fm1m[m][f]*llx1m[n][m]; fx2[n][f] += fm2p[m][f]*llx2p[n][m] - fm2m[m][f]*llx2m[n][m]; } /* //negative branch for (int m = 0; m < mellinint::mdim; m++) for (int f = 0; f < 2*MAXNF+1; f++) { // fx1[n][f] -= fm1m[m][f]*(1.-x1n[n]/conj(x1n[m]))/(mellinint::Np[n]-mellinint::Nm[m]); // fx2[n][f] -= fm2m[m][f]*(1.-x2n[n]/conj(x2n[m]))/(mellinint::Np[n]-mellinint::Nm[m]); fx1[n][f] -= fm1m[m][f]*llx1m[n][m]; fx2[n][f] -= fm2m[m][f]*llx2m[n][m]; } */ //cout << "truncated " << n << fx1[5] << endl; } //replace moments for (int n = 0; n < mellinint::mdim; n++) storemoments(n, fx1[n]); //storemoments(n, fx1[n], fx2[n]); } void pdfevol::uppertruncate() { //Calculate truncated moments double xmin1 = pow(phasespace::m/opts.sroot,2); double xmin2 = pow(phasespace::m/opts.sroot,2); double xmax1 = phasespace::m/opts.sroot*exp(phasespace::ymax); double xmax2 = phasespace::m/opts.sroot*exp(-phasespace::ymin); double lx1 = log(xmin1/xmax1); double lx2 = log(xmin2/xmax2); //truncated moments (output) complex fx1[mellinint::mdim][2*MAXNF+1] = {0.}; complex fx2[mellinint::mdim][2*MAXNF+1] = {0.}; //cache x^(N) values complex xmin1n[mellinint::mdim]; complex xmin2n[mellinint::mdim]; complex xmax1n[mellinint::mdim]; complex xmax2n[mellinint::mdim]; for (int n = 0; n < mellinint::mdim; n++) { xmin1n[n] = pow(xmin1,mellinint::Np[n]); xmin2n[n] = pow(xmin2,mellinint::Np[n]); xmax1n[n] = pow(xmax1,mellinint::Np[n]); xmax2n[n] = pow(xmax2,mellinint::Np[n]); } //Normalisation times Jacobian complex facp = mellinint::CCp/2./M_PI/complex (0.,1); complex facm = mellinint::CCm/2./M_PI/complex (0.,1); //original moments times prefactor and weight complex fm1p[mellinint::mdim][2*MAXNF+1]; complex fm2p[mellinint::mdim][2*MAXNF+1]; complex fm1m[mellinint::mdim][2*MAXNF+1]; complex fm2m[mellinint::mdim][2*MAXNF+1]; for (int m = 0; m < mellinint::mdim; m++) for (int f = 0; f < 2*MAXNF+1; f++) { fm1p[m][f] = facp * cx(creno_.cfx1_[m][f] ) * mellinint::wn[m]; fm2p[m][f] = facp * cx(creno_.cfx2p_[m][f]) * mellinint::wn[m]; fm1m[m][f] = facm * conj(cx(creno_.cfx1_[m][f]) ) * mellinint::wn[m]; fm2m[m][f] = facm * conj(cx(creno_.cfx2p_[m][f])) * mellinint::wn[m]; } //cache factor (xmax^(N-M)-xmin^(N-M))/(N-M) which limit is ln(xmin/xmax) when N-M -> 0 complex llx1p[mellinint::mdim][mellinint::mdim]; complex llx2p[mellinint::mdim][mellinint::mdim]; complex llx1m[mellinint::mdim][mellinint::mdim]; complex llx2m[mellinint::mdim][mellinint::mdim]; for (int n = 0; n < mellinint::mdim; n++) for (int m = 0; m < mellinint::mdim; m++) { llx1p[n][m] = (xmax1n[n]/xmax1n[m]-xmin1n[n]/xmin1n[m])/(mellinint::Np[n]-mellinint::Np[m]); llx2p[n][m] = (xmax2n[n]/xmax2n[m]-xmin2n[n]/xmin2n[m])/(mellinint::Np[n]-mellinint::Np[m]); llx1m[n][m] = (xmax1n[n]/conj(xmax1n[m])-xmin1n[n]/conj(xmin1n[m]))/(mellinint::Np[n]-mellinint::Nm[m]); llx2m[n][m] = (xmax2n[n]/conj(xmax2n[m])-xmin2n[n]/conj(xmin2n[m]))/(mellinint::Np[n]-mellinint::Nm[m]); } //overwrite divergent diagonal part for (int n = 0; n < mellinint::mdim; n++) { llx1p[n][n] = -lx1; llx2p[n][n] = -lx2; } for (int n = 0; n < mellinint::mdim; n++) { //positive branch for (int m = 0; m < mellinint::mdim; m++) for (int f = 0; f < 2*MAXNF+1; f++) { /* if (m == n) { fx1[n][f] += fm1p[m][f] * (-lx1); fx2[n][f] += fm2p[m][f] * (-lx2); } else { fx1[n][f] += fm1p[m][f] * (1.-x1n[n]/x1n[m])/(mellinint::Np[n]-mellinint::Np[m]); fx2[n][f] += fm2p[m][f] * (1.-x2n[n]/x2n[m])/(mellinint::Np[n]-mellinint::Np[m]); } */ // fx1[n][f] += fm1p[m][f]*llx1p[n][m]; // fx2[n][f] += fm2p[m][f]*llx2p[n][m]; fx1[n][f] += fm1p[m][f]*llx1p[n][m] - fm1m[m][f]*llx1m[n][m]; fx2[n][f] += fm2p[m][f]*llx2p[n][m] - fm2m[m][f]*llx2m[n][m]; } /* //negative branch for (int m = 0; m < mellinint::mdim; m++) for (int f = 0; f < 2*MAXNF+1; f++) { // fx1[n][f] -= fm1m[m][f]*(1.-x1n[n]/conj(x1n[m]))/(mellinint::Np[n]-mellinint::Nm[m]); // fx2[n][f] -= fm2m[m][f]*(1.-x2n[n]/conj(x2n[m]))/(mellinint::Np[n]-mellinint::Nm[m]); fx1[n][f] -= fm1m[m][f]*llx1m[n][m]; fx2[n][f] -= fm2m[m][f]*llx2m[n][m]; } */ //cout << "truncated " << n << fx1[5] << endl; } //replace moments for (int n = 0; n < mellinint::mdim; n++) storemoments(n, fx1[n]); //storemoments(n, fx1[n], fx2[n]); } /* void pdfevol::invert(double x, double fx[2*MAXNF+1]) { fx = {0.}; complex fm[2*MAXNF+1]; complex fm2[2*MAXNF+1]; double lx = log(x); //positive branch for (int m = 0; m < mellinint::mdim; m++) { complex cexp = mellinint::CCp/2./M_PI/complex (0.,1) * exp(-mellinint::Np[m] * lx); for (int f = 0; f < 2*MAXNF+1; f++) { fm[f] = cx(creno_.cfx1_[m][f]); fx[f] += cexp * fm[f] * mellinint::wn[m]; } //negative branch for (int m = 0; m < mellinint::mdim; m++) { complex cexm = mellinint::CCm/2./M_PI/complex (0.,1) * exp(-mellinint::Nm[m] * lx); for (int f = 0; f < 2*MAXNF+1; f++) { fm[f] = cx(creno_.cfx2m_[m][f]); fx1[f] -= mellinint::CCm/2./M_PI/complex (0.,1) * conj(fm1[f])*(1.-pow(x1,mellinint::Np[n]-mellinint::Nm[m]))/(mellinint::Np[n]-mellinint::Nm[m]) * mellinint::wn[m]; fx2[f] -= mellinint::CCm/2./M_PI/complex (0.,1) * conj(fm2[f])*(1.-pow(x2,mellinint::Np[n]-mellinint::Nm[m]))/(mellinint::Np[n]-mellinint::Nm[m]) * mellinint::wn[m]; } cout << "truncated " << n << fx1[5] << endl; } */ diff --git a/resum/pdfevol.h b/resum/pdfevol.h index 5ad8168..6b8aa8b 100644 --- a/resum/pdfevol.h +++ b/resum/pdfevol.h @@ -1,106 +1,108 @@ #ifndef pdfevol_h #define pdfevol_h #include "interface.h" #include using namespace std; extern "C" { void pdfmoments_(int &beam, double &scale, fcomplex &N, fcomplex &UV, fcomplex &DV, fcomplex &US, fcomplex &DS, fcomplex &SP, fcomplex &SM, fcomplex &GL, fcomplex &CH, fcomplex &BO, double &xmin); //access dyres PDF in N-space extern struct { // fcomplex cfx1_[136][11]; // fcomplex cfx2p_[136][11]; // fcomplex cfx2m_[136][11]; fcomplex cfx1_[512][11]; fcomplex cfx2p_[512][11]; fcomplex cfx2m_[512][11]; } creno_; } #pragma omp threadprivate(creno_) namespace pdfevol { //PDFs mellin moments at the factorisation scale extern complex *UVP; extern complex *DVP; extern complex *USP; extern complex *DSP; extern complex *SSP; extern complex *GLP; extern complex *CHP; extern complex *BOP; #pragma omp threadprivate(UVP,DVP,USP,DSP,SSP,GLP,CHP,BOP) //evolved PDFs mellin moments extern complex *fx1; extern complex *fx2; #pragma omp threadprivate(fx1,fx2) //moments for the PDFs convolution extern complex fn1[2*MAXNF+1]; extern complex fn2[2*MAXNF+1]; #pragma omp threadprivate(fn1,fn2) //scales extern complex bscale; extern complex bstarscale; extern complex bstartilde; extern complex qbstar; extern complex bcomplex; extern complex XL; extern complex XL1; extern complex SALP; extern complex alpr; #pragma omp threadprivate(bscale,bstarscale,bstartilde,qbstar,bcomplex,XL,XL1,SALP,alpr) extern void allocate(); //allocate dynamic memory extern void free(); //free dynamic memory extern void allocate_fx(); //allocate dynamic memory extern void free_fx(); //free dynamic memory //initialise and compute Mellin moments of PDFs at the starting scale (factorisation scale) extern void init(); + //release memory if fmufac = 0 + extern void release(); //update Mellin moments of PDFs at the starting scale with a dynamic factorisation scale extern void update(); //evolve Mellin moments of PDFs from the factorisation scale to the scale ~1/b, set in bscale extern void evolution(int i); //calculate Mellin moments of PDFs at all scales by direct Mellin transform extern void calculate(int i); extern void calculate(); //store the moments in the fx1 and fx2 arrays extern void storemoments(int i, complex fx[11]); //store the moments in the Fortran common block extern void storemoments_fortran(int i, complex fx[11]); //retrieve moments corresponding to i1, i2, and sign from the fx1 and fx2 arrays and store them in fn1 and fn2 extern void retrieve(int i1, int i2, int sign); //retrieve moments corresponding to i1, i2, and sign from the Fortran common block and store them in fn1 and fn2 extern void retrieve_fortran(int i1, int i2, int sign); //retrieve only fn1 extern void retrieve_beam1(int i1); //retrieve only fn2 positive extern void retrieve_beam2_pos(int i2); //retrieve only fn2 negative extern void retrieve_beam2_neg(); //flavour dependent form factors extern void flavour_kt(); //retrieve moments corresponding to i, and sign from fx1 and fx2 and store them in fn1 and fn2, to be used with the mellin1d option extern void retrieve1d(int i, int sign); //retrieve moments corresponding to i, and sign from the Fortran common block and store them in fn1 and fn2, to be used with the mellin1d option extern void retrieve1d_fortran(int i, int sign); extern void retrievemuf(int i, int sign); extern void truncate(); extern void uppertruncate(); } #endif diff --git a/resum/rapint.C b/resum/rapint.C index 14e2d3b..c4db8e3 100644 --- a/resum/rapint.C +++ b/resum/rapint.C @@ -1,253 +1,259 @@ #include "rapint.h" #include "settings.h" #include "gaussrules.h" #include "mellinint.h" #include "omegaintegr.h" #include "phasespace.h" #include int rapint::ydim; complex *rapint::cfpy; complex *rapint::cfmy; complex *rapint::Ith0p; complex *rapint::Ith1p; complex *rapint::Ith2p; complex *rapint::Ith0m; complex *rapint::Ith1m; complex *rapint::Ith2m; void rapint::init() { ydim = opts.yrule*opts.yintervals; //variables to cache the rapidity dependent exponentials cfpy = new complex [mellinint::mdim*mellinint::mdim*ydim]; cfmy = new complex [mellinint::mdim*mellinint::mdim*ydim]; } +void rapint::release() +{ + delete[] cfpy; + delete[] cfmy; +} + void rapint::cache(double ymin, double ymax) { //cache the rapidity dependent exponentials //The caching is done for the numerical integration, but can be done also for the analytical integration (need to calculate only the ymin and ymax exp) for (int i=0; i < opts.yintervals; i++) { double ya = ymin+(ymax-ymin)*i/opts.yintervals; double yb = ymin+(ymax-ymin)*(i+1)/opts.yintervals; double xc=0.5*(ya+yb); double xm=0.5*(yb-ya); for (int j=0; j < opts.yrule; j++) { double y=xc+xm*gr::xxx[opts.yrule-1][j]; for (int i1 = 0; i1 < mellinint::mdim; i1++) for (int i2 = 0; i2 < mellinint::mdim; i2++) { complex diffnpp = mellinint::Np[i1]-mellinint::Np[i2]; complex diffnpm = mellinint::Np[i1]-mellinint::Nm[i2]; cfpy[index(i,j,i1,i2)]=exp(-diffnpp*y)*mellinint::wn[i1]*mellinint::wn[i2]*gr::www[opts.yrule-1][j]*xm; cfmy[index(i,j,i1,i2)]=exp(-diffnpm*y)*mellinint::wn[i1]*conj(mellinint::wn[i2])*gr::www[opts.yrule-1][j]*xm; } } } } void rapint::allocate() { //allocate memory Ith0p = new complex [mellinint::mdim*mellinint::mdim]; Ith1p = new complex [mellinint::mdim*mellinint::mdim]; Ith2p = new complex [mellinint::mdim*mellinint::mdim]; Ith0m = new complex [mellinint::mdim*mellinint::mdim]; Ith1m = new complex [mellinint::mdim*mellinint::mdim]; Ith2m = new complex [mellinint::mdim*mellinint::mdim]; } void rapint::integrate(double ymin, double ymax, double m) { //integration results are stored in Ithxx //Initialize integrals for (int i1 = 0; i1 < mellinint::mdim; i1++) for (int i2 = 0; i2 < mellinint::mdim; i2++) { Ith0p[mellinint::index(i1,i2)] = 0.; Ith1p[mellinint::index(i1,i2)] = 0.; Ith2p[mellinint::index(i1,i2)] = 0.; Ith0m[mellinint::index(i1,i2)] = 0.; Ith1m[mellinint::index(i1,i2)] = 0.; Ith2m[mellinint::index(i1,i2)] = 0.; } double q2 = m*m; double bjx= q2/pow(opts.sroot,2); double ax = log(bjx); //double ax1 = (ax+2*y)/2.; //double ax2 = (ax-2*y)/2.; //Notice that in all the expressions, the dependence on I1, I2 is of the type I1+I2 or I1-I2 //Does it mean that the double loops on I1 I2 can be reduced to single loops on I1+I2 and I1-I2 to calculate all the exponentials? //Is it true for both analytical and numerical integration? //No, because Np[i1]+Np[i2] != Np[i1+i2] //If there are no cuts on the leptons, calculate the integrals analitically //Int_ymin^ymax (CCp/M_PI)^2 * exp(Np(i1)*ax1) * exp(Np(i2)*ax2) if (!opts.makecuts) //Analytical integration for (int i1 = 0; i1 < mellinint::mdim; i1++) for (int i2 = 0; i2 < mellinint::mdim; i2++) { complex yintp, yintm; //split between negative and positive y, so as to allow costh boundaries, and account for y+- sign flip on costh double ymn, ymx; ymn = min(0., ymin); ymx = min(0., ymax); if(ymn < 0) { phasespace::set_y((ymn+ymx)/2.); complex sumnpp = mellinint::Np[i1]+mellinint::Np[i2]; complex diffnpp = mellinint::Np[i1]-mellinint::Np[i2]; if (i1 == i2) yintp=pow(mellinint::CCp/M_PI,2)*exp(-sumnpp*ax/2.)*(ymx-ymn); else yintp=1./(-diffnpp)*pow(mellinint::CCp/M_PI,2)*exp(-sumnpp*ax/2.)*(exp(-diffnpp*ymx)-exp(-diffnpp*ymn)); complex sumnpm = mellinint::Np[i1]+mellinint::Nm[i2]; complex diffnpm = mellinint::Np[i1]-mellinint::Nm[i2]; //if (mellinint::Np[i1] == mellinint::Nm[i2]) // this never happens --> It happens for Talbot! if (i1 == 0 && i2 == 0 && opts.mellininv == 1) yintm=(mellinint::CCp/M_PI)*(mellinint::CCm/M_PI)*exp(-sumnpm*ax/2.)*(ymx-ymn); else yintm=1./(-diffnpm)*(mellinint::CCp/M_PI)*(mellinint::CCm/M_PI)*exp(-sumnpm*ax/2.)*(exp(-diffnpm*ymx)-exp(-diffnpm*ymn)); double cthmom0, cthmom1, cthmom2; omegaintegr::cthmoments(cthmom0,cthmom1,cthmom2); Ith0p[mellinint::index(i1,i2)] = cthmom0*yintp*mellinint::wn[i1]*mellinint::wn[i2]; Ith1p[mellinint::index(i1,i2)] = cthmom1*yintp*mellinint::wn[i1]*mellinint::wn[i2]; Ith2p[mellinint::index(i1,i2)] = cthmom2*yintp*mellinint::wn[i1]*mellinint::wn[i2]; Ith0m[mellinint::index(i1,i2)] = cthmom0*yintm*mellinint::wn[i1]*conj(mellinint::wn[i2]); Ith1m[mellinint::index(i1,i2)] = cthmom1*yintm*mellinint::wn[i1]*conj(mellinint::wn[i2]); Ith2m[mellinint::index(i1,i2)] = cthmom2*yintm*mellinint::wn[i1]*conj(mellinint::wn[i2]); } ymn = max(0., ymin); ymx = max(0., ymax); if (ymx > 0.) { phasespace::set_y((ymn+ymx)/2.); complex sumnpp = mellinint::Np[i1]+mellinint::Np[i2]; complex diffnpp = mellinint::Np[i1]-mellinint::Np[i2]; if (i1 == i2) yintp=pow(mellinint::CCp/M_PI,2)*exp(-sumnpp*ax/2.)*(ymx-ymn); else yintp=1./(-diffnpp)*pow(mellinint::CCp/M_PI,2)*exp(-sumnpp*ax/2.)*(exp(-diffnpp*ymx)-exp(-diffnpp*ymn)); complex sumnpm = mellinint::Np[i1]+mellinint::Nm[i2]; complex diffnpm = mellinint::Np[i1]-mellinint::Nm[i2]; if (i1 == 0 && i2 == 0 && opts.mellininv == 1) yintm=(mellinint::CCp/M_PI)*(mellinint::CCm/M_PI)*exp(-sumnpm*ax/2.)*(ymx-ymn); else yintm=1./(-diffnpm)*(mellinint::CCp/M_PI)*(mellinint::CCm/M_PI)*exp(-sumnpm*ax/2.)*(exp(-diffnpm*ymx)-exp(-diffnpm*ymn)); double cthmom0, cthmom1, cthmom2; omegaintegr::cthmoments(cthmom0,cthmom1,cthmom2); Ith0p[mellinint::index(i1,i2)] += cthmom0*yintp*mellinint::wn[i1]*mellinint::wn[i2]; Ith1p[mellinint::index(i1,i2)] += cthmom1*yintp*mellinint::wn[i1]*mellinint::wn[i2]; Ith2p[mellinint::index(i1,i2)] += cthmom2*yintp*mellinint::wn[i1]*mellinint::wn[i2]; Ith0m[mellinint::index(i1,i2)] += cthmom0*yintm*mellinint::wn[i1]*conj(mellinint::wn[i2]); Ith1m[mellinint::index(i1,i2)] += cthmom1*yintm*mellinint::wn[i1]*conj(mellinint::wn[i2]); Ith2m[mellinint::index(i1,i2)] += cthmom2*yintm*mellinint::wn[i1]*conj(mellinint::wn[i2]); } } else //Numerical integration { //cache the mass dependent part (ax) of the exponential //The caching is done for the numerical integration only, but can be done also for the analytical integration (there is no gain in speed, but the code would be cleaner) complex cfpm[mellinint::mdim][mellinint::mdim]; complex cfmm[mellinint::mdim][mellinint::mdim]; for (int i1 = 0; i1 < mellinint::mdim; i1++) for (int i2 = 0; i2 < mellinint::mdim; i2++) { //Reduce by a factor of 2 the number of exponentials (only upper diagonal triangle) the positive piece is symmetric under i1 <-> i2 //In the negative piece exchange of i1 <-> i2 needs a complex conjugate if (i2 >= i1) { complex sumnpp = mellinint::Np[i1]+mellinint::Np[i2]; complex sumnpm = mellinint::Np[i1]+mellinint::Nm[i2]; cfpm[i1][i2]=pow(mellinint::CCp/M_PI,2)*exp(-sumnpp*ax/2.); cfmm[i1][i2]=mellinint::CCp*mellinint::CCm/pow(M_PI,2)*exp(-sumnpm*ax/2.); } else { cfpm[i1][i2]=cfpm[i2][i1]; cfmm[i1][i2]=conj(cfmm[i2][i1]); } } // start integration double xc=0.5*(ymin+ymax); double xm=0.5*(ymax-ymin); for (int i=0; i < opts.yintervals; i++) { double ya = ymin+(ymax-ymin)*i/opts.yintervals; double yb = ymin+(ymax-ymin)*(i+1)/opts.yintervals; xc=0.5*(ya+yb); xm=0.5*(yb-ya); for (int j=0; j < opts.yrule; j++) { double y=xc+xm*gr::xxx[opts.yrule-1][j]; //calculate costheta moments as a function of y phasespace::set_y(y); omegaintegr::genV4p(); double cthmom0, cthmom1, cthmom2; omegaintegr::cthmoments(cthmom0,cthmom1,cthmom2); //cout << cthmom0 << " " << cthmom1 << " " << cthmom2 << endl; for (int i1 = 0; i1 < mellinint::mdim; i1++) for (int i2 = 0; i2 < mellinint::mdim; i2++) { //if (i2 >= i1) //Be careful!!! can symmetrise this only for lepton charge-symmetric cuts // { //functions to integrate (rapidity part is cached at initialisation) complex fpy=cfpm[i1][i2]*cfpy[index(i, j, i1, i2)]; complex fmy=cfmm[i1][i2]*cfmy[index(i, j, i1, i2)]; //integrals Ith0p[mellinint::index(i1,i2)]+=fpy*cthmom0; Ith1p[mellinint::index(i1,i2)]+=fpy*cthmom1; Ith2p[mellinint::index(i1,i2)]+=fpy*cthmom2; Ith0m[mellinint::index(i1,i2)]+=fmy*cthmom0; Ith1m[mellinint::index(i1,i2)]+=fmy*cthmom1; Ith2m[mellinint::index(i1,i2)]+=fmy*cthmom2; // } //else // { // Ith0p[mellinint::index(i1,i2)]=Ith0p[mellinint::index(i2,i1)]; // Ith1p[mellinint::index(i1,i2)]=Ith1p[mellinint::index(i2,i1)]; // Ith2p[mellinint::index(i1,i2)]=Ith2p[mellinint::index(i2,i1)]; // Ith0m[mellinint::index(i1,i2)]=conj(Ith0m[mellinint::index(i2,i1)]); // Ith1m[mellinint::index(i1,i2)]=conj(Ith1m[mellinint::index(i2,i1)]); // Ith2m[mellinint::index(i1,i2)]=conj(Ith2m[mellinint::index(i2,i1)]); // } } } } // for (int i1 = 0; i1 < 3; i1++) // for (int i2 = 0; i2 < 3; i2++) // cout << i1 << " " << i2 << " " << Ith1p[mellinint::index(i1,i2)] << " " << cfpm[i1][i2] << endl; } //for (int i1 = 0; i1 < 3; i1++) //for (int i2 = 0; i2 < 3; i2++) //cout << i1 << " " << i2 << " " << Ith0p[mellinint::index(i1,i2)] << " " << Ith0m[mellinint::index(i1,i2)] << endl; } void rapint::free() { //integration results delete[] Ith0p; delete[] Ith1p; delete[] Ith2p; delete[] Ith0m; delete[] Ith1m; delete[] Ith2m; } diff --git a/resum/rapint.h b/resum/rapint.h index 4fe9321..f9b4204 100644 --- a/resum/rapint.h +++ b/resum/rapint.h @@ -1,42 +1,43 @@ #ifndef rapint_h #define rapint_h #include #include "mellinint.h" #include "settings.h" using namespace std; namespace rapint { extern int ydim; void init(); + void release(); extern complex * cfpy; extern complex * cfmy; void cache(double ymin, double ymax); extern complex *Ith0p; extern complex *Ith1p; extern complex *Ith2p; extern complex *Ith0m; extern complex *Ith1m; extern complex *Ith2m; #pragma omp threadprivate(Ith0p,Ith1p,Ith2p,Ith0m,Ith1m,Ith2m) void allocate(); void integrate(double m, double ymin, double ymax); void free(); inline int index(int i, int j, int i1, int i2) {return i2 + mellinint::mdim*(i1 + mellinint::mdim*(j + opts.yrule*i));} } extern "C" { inline void rapint_cache_(double& ymin, double& ymax) {rapint::cache(ymin, ymax);}; inline void rapint_integrate_(double& ymin, double& ymax, double& m) {rapint::integrate(ymin, ymax, m);}; } #endif diff --git a/resum/resconst.C b/resum/resconst.C index 86c668a..8aa092b 100644 --- a/resum/resconst.C +++ b/resum/resconst.C @@ -1,81 +1,80 @@ #include "resconst.h" -#include "interface.h" #include // constants.f const int resconst::NF = 5; const double resconst::CA = 3.; const double resconst::Cf = 4./3.; const double resconst::Euler = 0.57721566; const double resconst::Z2 = 1.64493406685; //1.644934; const double resconst::Z3 = 1.20205690316;// 1.202057; //higher precision /* const double resconst::Euler = 0.57721566490153286; const double resconst::Z2 = M_PI*M_PI/6.; const double resconst::Z3 = 1.2020569031595942853; */ double resconst::b0; double resconst::beta0, resconst::beta1, resconst::beta2, resconst::Kappa; double resconst::A1g, resconst::A2g, resconst::A3g, resconst::B1g, resconst::B2g, resconst::C1ggn; double resconst::A1q, resconst::A2q, resconst::A3q, resconst::B1q, resconst::B2q, resconst::C1qqn; double resconst::C1qqdelta, resconst::Delta2qq; double resconst::D0qqqq, resconst::D1qqqq; double resconst::Deltaqqqq; double resconst::H2qqdelta; double resconst::H2qqD0; void resconst::init() { double pi2 = M_PI*M_PI; double pi4 = pi2*pi2; double nf2 = NF*NF; b0=2*exp(-Euler); //Resummation coefficients beta0=(33.-2.*NF)/12.; beta1=(153.-19.*NF)/24.; beta2=2857./128.-5033.*NF/1152.+325.*nf2/3456.; Kappa=67./6.-pi2/2.-5./9.*NF; //gluon coefficients A1g=CA; A2g=CA/2.*(67./6.-pi2/2.-5./9.*NF); //CA/2.*Kappa; A3g=CA*(13.81-2.15*NF-nf2/108.); B1g=-(11.*CA-2.*NF)/6.; B2g=CA*CA*(23./24.+(11.*pi2)/18.-3.*Z3/2.)+Cf*NF/2.-CA*NF*(1./12.+pi2/9.)-11./8.*Cf*CA; C1ggn=(pi2/2.+11./2.+pi2)/2.; //quark coefficients A1q=Cf; //4./3; A2q=Cf/2.*Kappa; //(67./6.-pi2/2.-5./9.*NF); A3q=Cf*(13.81-2.15*NF-nf2/108.)+Cf*(CA*(29.9259-28.*Z3)-8.2963*NF/2.)*2.*(beta0*4.)/64.; //A3 from Becher & Neubert B1q=-(3.*Cf)/2.; //-2; B2q=Cf*Cf*(pi2/4.-3./16.-3.*Z3)+CA*Cf*(11*pi2/36.-193./48.+3.*Z3/2.)+Cf*NF*(17./24.-pi2/18.); //B2q=4./9.*(pi2-3./4.-12.*Z3)+(11./9.*pi2-193./12.+6.*Z3)+NF/6.*(17./3.-4./9.*pi2); C1qqn=Cf/2.*(pi2/2.-4.); // Only delta(1-z) part, i.e. N independent part // Delta term in c1qq coefficient C1qqdelta=(pi2-8.)/3.; // Delta term in P2qq splitting function (as/M_PI normalization) Delta2qq=16./9.*(3./8.-pi2/2.+6.*Z3)+4.*(17./24.+11.*pi2/18.-3.*Z3)-2./3.*NF*(1./6.+2.*pi2/9.); Delta2qq=Delta2qq/4.; // Coefficients of D0 and D1 in P*P (as/M_PI normalization) D0qqqq=8./3.; D1qqqq=32./9.; // Coefficients of delta(1-z) in P*P Deltaqqqq=4./9.*(9./4.-2.*pi2/3.); // H2qq contribution: coefficient of delta(1-z) H2qqdelta=-2561./144.+127.*NF/72.+3.*pi2/2.-19.*NF*pi2/81.+49.*pi4/324.+58.*Z3/9.+8.*NF*Z3/27.; // H2qq contribution: coefficient of D0(z) H2qqD0=-404./27.+(56.*NF)/81.+14.*Z3; } diff --git a/resum/resint.C b/resum/resint.C index 7905c54..1241d41 100644 --- a/resum/resint.C +++ b/resum/resint.C @@ -1,955 +1,954 @@ #include "resint.h" #include "phasespace.h" #include "settings.h" #include "dyres_interface.h" #include "resconst.h" #include "mesq.h" #include "omegaintegr.h" #include "gaussrules.h" #include "hcoefficients.h" #include "hcoeff.h" #include "pdfevol.h" #include "besselint.h" #include "cubature.h" #include "pdf.h" #include "scales.h" #include "sudakovff.h" #include "besche_interface.h" #include "hankel.h" #include "minprescription_interface.h" #include "specialfunctions_interface.h" #include "588_interface.h" #include #include "intde2_c.h" #include double tiny = 1.0e-307; double awinf[lenaw]; double awdei[lenaw]; //double awfin[lenaw]; double resint::_qt; double resint::_m; double resint::_y; double resint::_costh; double resint::tau; double resint::x1; double resint::x2; int resint::_mode; double resint::muren; double resint::mufac; double resint::mures; double resint::muren2; double resint::mufac2; double resint::mures2; double resint::a; complex resint::loga; double resint::rloga; complex resint::logmuf2q2; complex resint::logq2muf2; complex resint::logq2mur2; double resint::rlogq2mur2; double resint::alpqr; double resint::alpqf; double resint::aass; double resint::alpqfac; double resint::alpqren; double resint::alpqres; double resint::bc; //using namespace resint; //#pragma omp threadprivate(_qt,_m,_y,_costh,_mode,muren,mufac,mures,muren2,mufac2,mures2,a,loga,rloga,logmuf2q2,logq2muf2,logq2mur2,rlogq2mur2,alpqr,alpqf,aass,alpqfac,alpqren,alpqres) extern "C" { double besselint_besche_(double &x) { return real(besselint::bint(x)); } double bint_mp_up_real_(double &x) { complex jac(cos(M_PI/opts.phibr),sin(M_PI/opts.phibr)); complex b = resint::bc + jac*x; fcomplex arg = fcx(resint::_qt*b); return real(besselint::bint(b)*jac*cx(h1_(arg))); } double bint_mp_up_imag_(double &x) { complex jac(cos(M_PI/opts.phibr),sin(M_PI/opts.phibr)); complex b = resint::bc + jac*x; fcomplex arg = fcx(resint::_qt*b); return imag(besselint::bint(b)*jac*cx(h1_(arg))); } double bint_mp_dn_real_(double &x) { complex jac(cos(M_PI/opts.phibr),-sin(M_PI/opts.phibr)); complex b = resint::bc + jac*x; fcomplex arg = fcx(resint::_qt*b); return real(besselint::bint(b)*jac*cx(h2_(arg))); } double bint_mp_dn_imag_(double &x) { complex jac(cos(M_PI/opts.phibr),-sin(M_PI/opts.phibr)); complex b = resint::bc + jac*x; fcomplex arg = fcx(resint::_qt*b); return imag(besselint::bint(b)*jac*cx(h2_(arg))); } // double besselint_mp_real_(double &x) // { // return besselint_mp_real_dequad(x); // } } int besselint_cubature(unsigned ndim, const double x[], void *data, unsigned ncomp, double f[]) { f[0] = real(besselint::bint(x[0])); return 0; } double besselint_dequad(double x) { return real(besselint::bint(x)); } double besselint_hankel(double x) { double qtb = x*resint::_qt; return real(besselint::bint(x))/x/fort_besj0_(qtb); } double besselint_588(double &x) { double qtb = x*resint::_qt; return real(besselint::bint(x))/fort_besj0_(qtb); } double besselint_mp_real_dequad(double x) { /* complex jacu(cos(M_PI/opts.phibr),sin(M_PI/opts.phibr)); complex bu = resint::bc + jacu*x; fcomplex argu = fcx(resint::_qt*bu); complex jacd(cos(M_PI/opts.phibr),-sin(M_PI/opts.phibr)); complex bd = resint::bc + jacd*x; fcomplex argd = fcx(resint::_qt*bd); complex h1, h2; // //call modified Hankel functions // h1 = cx(h1_(argu)); // h2 = cx(h2_(argd)); // //cout << bu << " " << h1 << " " << bd << " " << h2 << endl; //call original Hankel functions int n = 1; int nm; fcomplex chf1[2], chd1[2], chf2[2], chd2[2]; ch12n_ (n, argu, nm, chf1, chd1, chf2, chd2); h1 = cx(chf1[0]); ch12n_ (n, argd, nm, chf1, chd1, chf2, chd2); h2 = cx(chf2[0]); //cout << endl; //cout << " b " << bu << " " << bd << " bint " << besselint::bint(bu) << " " << besselint::bint(bd) << " h " << h1 << " " << h2 << " jac " << jacu << " " << jacd << endl; //return (real(besselint::bint(bu)*jacu*h1) + real(besselint::bint(bd)*jacd*h2))/2.; */ //Real axis integration (phib = 0) double bb = resint::bc + x; double qtb = bb*resint::_qt; complex bint = besselint::bint(bb); double J0 = fort_besj0_(qtb); double Y0 = fort_besy0_(qtb); double res = real(bint)*J0-imag(bint)*Y0; //cout << " b " << bb << " " << " bint " << bint << " J0 " << J0 << " " << Y0 << endl; //cout << " b " << bb << " h " << (real(besselint::bint(bu)*jacu*h1) + real(besselint::bint(bd)*jacd*h2))/2. << " j " << res << endl; return res; } double besselint_mp_complex_dequad(double x) { complex jacu(cos(M_PI/opts.phibr),sin(M_PI/opts.phibr)); complex bu = resint::bc + jacu*x; fcomplex qtbu = fcx(resint::_qt*bu); complex jacd(cos(M_PI/opts.phibr),-sin(M_PI/opts.phibr)); complex bd = resint::bc + jacd*x; fcomplex qtbd = fcx(resint::_qt*bd); complex h1, h2; // //call modified Hankel functions // h1 = cx(h1_(qtbu)); // h2 = cx(h2_(qtbd)); // //cout << bu << " " << h1 << " " << bd << " " << h2 << endl; //call original Hankel functions int n = 1; int nm; fcomplex chf1[2], chd1[2], chf2[2], chd2[2]; ch12n_ (n, qtbu, nm, chf1, chd1, chf2, chd2); h1 = cx(chf1[0]); ch12n_ (n, qtbd, nm, chf1, chd1, chf2, chd2); h2 = cx(chf2[0]); //cout << endl; //cout << " b " << bu << " " << bd << " bint " << besselint::bint(bu) << " " << besselint::bint(bd) << " h " << h1 << " " << h2 << " jac " << jacu << " " << jacd << endl; //Compute Hankel functions from fortran bessel functions (does not work, because they accept only real values...) //h1 = complex (fort_besj0_(qtbu), fort_besy0_(qtbu)); //h2 = complex (fort_besj0_(qtbd), -fort_besy0_(qtbd)); //h2 = conj(h1); complex bint_up = besselint::bint(bu); complex bint_dn = besselint::bint(bd); //complex bint_dn = conj(besselint::bint(bu)); return (real(bint_up*jacu*h1) + real(bint_dn*jacd*h2))/2.; //return real(bint_up*jacu*h1); } double frealu_dequad(double x) { complex jacu(cos(M_PI/opts.phibr),sin(M_PI/opts.phibr)); complex bu = resint::bc + jacu*x; fcomplex argu = fcx(resint::_qt*bu); complex h1; //call modified Hankel functions /* h1 = cx(h1_(argu)); //cout << bu << " " << h1 << endl; */ //call original Hankel functions int n = 1; int nm; fcomplex chf1[2], chd1[2], chf2[2], chd2[2]; ch12n_ (n, argu, nm, chf1, chd1, chf2, chd2); h1 = cx(chf1[0]); return real(besselint::bint(bu)*jacu*h1); } double freald_dequad(double x) { complex jacd(cos(M_PI/opts.phibr),-sin(M_PI/opts.phibr)); complex bd = resint::bc + jacd*x; fcomplex argd = fcx(resint::_qt*bd); complex h2; //call modified Hankel functions /* h2 = cx(h2_(argd)); //cout << bd << " " << h2 << endl; */ //call original Hankel functions int n = 1; int nm; fcomplex chf1[2], chd1[2], chf2[2], chd2[2]; ch12n_ (n, argd, nm, chf1, chd1, chf2, chd2); h2 = cx(chf2[0]); return real(besselint::bint(bd)*jacd*h2); } void resint::init() { //Set values in the common block for the sudakov flag1_.flag1_ = opts.order; //order for the sudakov iorder_.iord_ = opts.order - 1; //order for LL/NLL running of alphas //modified_.imod_ = 1; // normal (imod=0) or modified (imod=1) sudakov modified_.imod_ = opts.modlog; // canonical (imod=0) or modified (imod=1) logarithms in the Sudakov // choose real axis (complex plane) integration of bstar (b) (always 0) if (opts.bprescription == 2 || opts.bprescription == 3) flagrealcomplex_.flagrealcomplex_ = 1; else flagrealcomplex_.flagrealcomplex_ = 0; //v parameter of the modified Hankel functions v_.v_=1.; //g-parameter of the non perturbative form factor np_.g_ = opts.g_param; //a-parameter of the resummation scale, set it for the dynamic case if (opts.fmures > 0) { a = 1./opts.kmures; a_param_.a_param_ = a; a_param_.b0p_ = resconst::b0*a; // precompute log of scales loga = log(a); rloga = log(a); rlogs_.rloga_ = rloga; // clogs_.loga_ = loga; //complex loga is not used } // define points for quadratures integration intdeoini(lenaw, tiny, opts.bintaccuracy, awinf); //intdeoini(lenaw, tiny, 1.0e-6, awinf); //intdeiini(lenaw, tiny, 1.0e-6, awdei); //intdeini(lenaw, tiny, 1.0e-2, awfin); } double resint::rint(double costh, double m, double qt, double y, int mode) { /* //limit the integration to qt = m double jac = 1; double qtp = qt; if (qtp >= m*0.999) return 0.; else qt = qtp/sqrt(1-pow(qtp/m,2)); jac = pow(m/sqrt(m*m-qtp*qtp),3); */ //point in phase space (should use the phasespace namespace instead of storing them in resint) _qt = qt; _y = y; _m = m; _costh = costh; //compute x1 and x2 for the NP ff double exppy = exp(y); double expmy = 1./exppy; tau = m/opts.sroot; x1 = tau*exppy; x2 = tau*expmy; //mode 0: differential //mode 1: integrated in costh //mode 2: integrated in costh and y //mode 3: integrated in costh, y, and pt _mode = mode; // Kinematical limit in rapidity double q2 = m*m; double x = q2/pow(opts.sroot,2); double ax = log(x); double ylim=-0.5*ax; if (abs(y) > ylim) return 0; //move the scale setting to an independent namelist, so it can be called by all the calculations scales::set(m); muren = scales::ren; mufac = scales::fac; mures = scales::res; //for fixed resummation scale need to recompute a_param if (opts.fmures == 0) { a = m/mures; loga = log(a); rloga = log(a); a_param_.a_param_ = a; a_param_.b0p_ = resconst::b0*a; rlogs_.rloga_ = rloga; } /* //Set factorization and renormalization scales (set dynamic scale here) if (opts.dynamicscale) { muren = m*opts.kmuren; mufac = m*opts.kmufac; } else { muren = opts.rmass*opts.kmuren; mufac = opts.rmass*opts.kmufac; } if (opts.dynamicresscale) mures = m*opts.kmures; else //for fixed resummation scale need to recompute a_param { mures = opts.rmass*opts.kmures; a = m/mures; loga = log(a); rloga = log(a); a_param_.a_param_ = a; a_param_.b0p_ = resconst::b0*a; rlogs_.rloga_ = rloga; } */ muren2=pow(muren,2); mufac2=pow(mufac,2); mures2=pow(mures,2); //update PDFs in Mellin space at the starting scale, if the factorisation scale is proportional to mll if (opts.fmufac > 0) { pdfevol::allocate(); pdfevol::update(); } //alphas at various scales (alphas convention is alphas/4/pi) - alpqren=LHAPDF::alphasPDF(muren)/4./M_PI; - alpqfac=LHAPDF::alphasPDF(mufac)/4./M_PI; - alpqres=LHAPDF::alphasPDF(mures)/4./M_PI; + //alpqren=LHAPDF::alphasPDF(muren)/4./M_PI; + //alpqfac=LHAPDF::alphasPDF(mufac)/4./M_PI; + //alpqres=LHAPDF::alphasPDF(mures)/4./M_PI; + alpqren=pdf::alphas(muren)/4./M_PI; + alpqfac=pdf::alphas(mufac)/4./M_PI; + alpqres=pdf::alphas(mures)/4./M_PI; + //alpqr is alphas at the renormalization scale if (opts_.approxpdf_ == 1) { int nloop = 3; double scale = muren; alpqr=dyalphas_mcfm_(scale,couple_.amz_,nloop)/4./M_PI; } else alpqr=alpqren; //alpqf is alphas at the resummation scale. It is used as starting scale for the PDF evolution if (opts_.approxpdf_ == 1) { int nloop = 3; double scale = mures; alpqf=dyalphas_mcfm_(scale,couple_.amz_,nloop)/4./M_PI; } else alpqf=alpqres; /***************************************************/ //set values in the common blocks for the sudakov //aaas is alphas/pi at renormalization scale aass = alpqr*4.; aass_.aass_ = aass; double q = m; double blim; //dynamic blim if (opts.blim < 0) { //if (opts.order == 2 && q2 > 2.2*muren2) //avoid large values of b in f2(y) when q2>mur2 if (q2 > 2.2*muren2) //avoid large values of b in f2(y) when q2>mur2 blim = a_param_.b0p_*(1./q)*exp(1./(2.*aass*resconst::beta0))*sqrt(muren2/q2); else blim = a_param_.b0p_*(1./q)*exp(1./(2.*aass*resconst::beta0)); // avoid Landau pole /* double lambdaqcd = muren/(exp(1./(2.*aass*resconst::beta0))); //--> corresponds to a divergence in alphas double lambdasudakov = mures/(exp(1./(2.*aass*resconst::beta0))); //--> correspond to a divergence in the Sudakov //should blim depend or not on a_param? In principle yes because PDFs are evolved to b0/bstar*a blim = min(resconst::b0/lambdaqcd,resconst::b0/lambdasudakov); //cout << _m << " " << resconst::b0/lambdaqcd << " " << resconst::b0/lambdasudakov << " " << a_param_.b0p_*(1./q)*exp(1./(2.*aass*resconst::beta0)) << endl; */ blim = blim/(opts.blim*(-1)); } //fixed blim if (opts.blim > 0) blim = opts.blim; // blim = 100; // blim = 4.0; // blim = 1.5; blimit_.rblim_ = blim; blimit_.cblim_ = fcx(blim); // cout << q << " " << mur << " " << blimit_.rblim_ << " " << a_param_.b0p_/lambdaqcd << " " << lambdaqcd <<" " << a_param_.b0p_/blim << endl; //fill in common block for scales (used in the sudakov) scaleh_.qt_ = _qt; scaleh_.qt2_ = _qt*_qt; scaleh_.xtau_ = 0.; scaleh_.q_ = _m; scaleh_.q2_ = _m*_m; scaleh_.shad_ = pow(opts.sroot,2); scaleh_.sroot_ = opts.sroot; scaleh_.mur_ = muren; scaleh_.mur2_ = muren2; scaleh_.muf_ = mufac; scaleh_.muf2_ = mufac2; /***************************************************/ //****************************************** // Initialise the born-level matrix elements mesqij // ---> mesqij depends on mass and costh // when costh is integrated and costh moments are provided, mesqij_expy // are convoluted with the rapidity depent expression // and they depend also on rapidity if (!(opts.order == 0 && opts.xspace)) { mesq::allocate(); mesq::setmesq_expy(mode, m, costh, y); } else //No Mellin transform case { mesq::setpropagators(m); if (mode == 0) //costh differential mesq::setmesq(1., costh, pow(costh,2)); else //costh integrated { double cthmom0, cthmom1, cthmom2; omegaintegr::cthmoments(cthmom0, cthmom1, cthmom2); mesq::setmesq(cthmom0, cthmom1, cthmom2); } } //****************************************** //***************************************** //precompute scales: there is mass dependence in logq2muf2 logq2mur2, only with fixed factorization and renormalization scales logmuf2q2=log(mufac2/q2); logq2muf2=log(q2/mufac2); logq2mur2=log(q2/muren2); rlogq2mur2=log(q2/muren2); rlogs_.rlogq2mur2_ = real(logq2mur2); //no need to recompute coefficients with variable scales //if (!dynamicscale || fixedresummationscale) if (opts.mellin1d) { hcoeff::allocate(); hcoeff::calc(aass,logmuf2q2,logq2muf2,logq2mur2,loga); } else { hcoefficients::allocate(); hcoefficients::calc(aass,logmuf2q2,logq2muf2,logq2mur2,loga); } pdfevol::allocate_fx(); //***************************************** double res; if (mode == 3) { /* Since qt appears only in the Bessel function J_0(bqt), the integration in qt could be factorised by using the following result: int_a^b J0(x) dx = Lambda0(b) - Lambda0(a) where Lambda0(x) = xJ0(x) + pi x/2 [J1(x)H0(x) - J0(x)H1(x)], with Hn Struve functions. !!! Things are actually much simpler because there is a qt factor (res *= qt/2./pow(opts.sroot,2);) !!! int_a^b x J0(x) dx = b J1(b) - a J1(a) See http://fisica.ciens.ucv.ve/~svincenz/TISPISGIMR.pdf and http://web.eah-jena.de/~rsh/Forschung/Stoer/besint.pdf (1.1.1) !!! The problem with this is the switching function, which depends on qt !!! --> The approach would be valid only for qt < m*k Now the integration call will automatically switch to mode = 2 for bins where qtmax > mmin*k */ //double qtmn = max(opts.qtcutoff,phasespace::qtmin); double qtmn = phasespace::qtmin; //double kinqtlim = sqrt(max(0.,pow(pow(opts.sroot,2)+phasespace::m2,2)/(4*pow(opts.sroot,2))-phasespace::m2)); //introduced max to avoid neqative argument of sqrt double kinqtlim = 1e10; double switchqtlim = opts.damp?phasespace::m*opts.dampk:1e10; //here use the value of qt where the switching start double qtlim = min(kinqtlim, switchqtlim); double qtmx = min(qtlim, phasespace::qtmax); if (qtmn >= qtmx || qtmx < opts.qtcutoff) res = 0; else { double res2, err2; _qt = qtmx; intdeo(besselint_dequad, 0.0, qtmx, awinf, &res2, &err2); double res1, err1; _qt = qtmn; if (qtmn < opts.qtcutoff) res1 = 0.; else intdeo(besselint_dequad, 0.0, qtmn, awinf, &res1, &err1); res = qtmx*res2 - qtmn*res1; // Normalization res *= 1./2./pow(opts.sroot,2); //cout << " res " << res << endl; } } else { // //if (opts.fast && opts.xspace) { // //Fast function // res = exp(-qt); // // // Normalization // double shad = pow(opts.sroot,2); // res *= qt/shad; // //} // //else // //{ //***************************************** //dependence on qt, m, also y, and costh unless integrated //perform b integration (int_0^inf db) res = bintegral(qt); // cout << "phase space point in resumm" << " " << _qt << " " << _y << " " << _m << " " << _costh << " " << res << endl; //***************************************** // Normalization res *= qt/2./pow(opts.sroot,2); } //Do not need the Mellin transform for the LL case, because the HN coefficient is 1 --> Use PDFs in x space if (opts.order == 0 && opts.xspace && (opts.evolmode == 0 || opts.evolmode == 1)) { double fun = 0.; if (mode < 2) //rapidity differential { //PDFs double fx1[2*MAXNF+1],fx2[2*MAXNF+1]; fdist_(opts.ih1,x1,mufac,fx1); fdist_(opts.ih2,x2,mufac,fx2); for (int sp = 0; sp < mesq::totpch; sp++) fun += fx1[mesq::pid1[sp]]*fx2[mesq::pid2[sp]]*real(mesq::mesqij[sp]); } else //rapidity integration { for (int i=0; i < opts.yintervals; i++) { double ya = phasespace::ymin+(phasespace::ymax-phasespace::ymin)*i/opts.yintervals; double yb = phasespace::ymin+(phasespace::ymax-phasespace::ymin)*(i+1)/opts.yintervals; double xc = 0.5*(ya+yb); double xm = 0.5*(yb-ya); for (int j=0; j < opts.yrule; j++) { double y = xc+xm*gr::xxx[opts.yrule-1][j]; double exppy = exp(y); double expmy = 1./exppy; x1 = tau*exppy; x2 = tau*expmy; //PDFs double fx1[2*MAXNF+1],fx2[2*MAXNF+1]; fdist_(opts.ih1,x1,mufac,fx1); fdist_(opts.ih2,x2,mufac,fx2); for (int sp = 0; sp < mesq::totpch; sp++) fun += fx1[mesq::pid1[sp]]*fx2[mesq::pid2[sp]]*real(mesq::mesqij[sp])*gr::www[opts.yrule-1][j]*xm;; } } } res *= fun; } //free allocated Local Thread Storage (LTS) memory if (opts.mellin1d) hcoeff::free(); else hcoefficients::free(); if (!(opts.order == 0 && opts.xspace)) mesq::free(); if (opts.fmufac > 0) pdfevol::free(); pdfevol::free_fx(); //res *= jac;//jacobian for the change of variable qt=qtp/sqrt(1-qtp^2/m^2) return res; } double resint::bintegral(double qt) { double res, err; - if (!opts.vfnsudakov) - { - //Warning!!! even if the sudakov is not VFN, when evolmode = 4, the integrand of bessel transform is discontinous at mb and mc - //--> Need to split the integral in this case + //Warning!!! when evolmode = 4, the integrand of bessel transform is discontinous at mb and mc + //--> Need to split the integral in this case - // Compute integral using double exponential quadratures for oscillatory fuctions (intde2.c) - sudakov::setnf(5); - - //bstar prescription - if (opts.bprescription == 0) - { - //intdeo(besselint::bint, 0.0, qt, awinf, &res, &err); - intdeo(besselint_dequad, 0.0, qt, awinf, &res, &err); - if (err < 0) - cout << "warning: dequad abnormal termination, pt=" << _qt << " m=" << _m << " y=" << _y << " bint: " << res << " err " << err << endl; - - /* - //test alternative integrations - cout << endl; - cout << "dequad result of inverse bessel transform, pt=" << _qt << " m=" << _m << " y=" << _y << " : " << setprecision(16) << res << " +- " << err << endl; - hankel::init(0,0,0.1); - hankel::transform(besselint_hankel, qt, res, err); - hankel::free(); - cout << "hankel result " << res << " +- " << err << endl; - cout.precision(6); cout.unsetf(ios_base::floatfield); - - //input - int nb = 1; //lagged convolutions - int nrel = 1; //related convolutions - int ntol = 1; - int nord[1] = {0}; //order of the transform - int ijrel[2*1]; //exponents of the related convolutions (not used) - double dwork [1*801]; //work array - //output - double dans[1*1]; //result - double arg[1]; //arguments of the lagged convolutions - int nofun1; //number of function evalutions - int ierr; //error code - dhankl_(qt, nb, nrel, opts.bintaccuracy, ntol, nord, besselint_588, ijrel, dwork, dans, arg, nofun1, ierr); - res = dans[0]; - err = 0.; - cout << "588 result " << res << " +- " << err << " " << nofun1 << endl; - cout.precision(6); cout.unsetf(ios_base::floatfield); - */ + // Compute integral using double exponential quadratures for oscillatory fuctions (intde2.c) + sudakov::setnf(5); + + //bstar prescription + if (opts.bprescription == 0) + { + //intdeo(besselint::bint, 0.0, qt, awinf, &res, &err); + intdeo(besselint_dequad, 0.0, qt, awinf, &res, &err); + if (err < 0) + cout << "warning: dequad abnormal termination, pt=" << _qt << " m=" << _m << " y=" << _y << " bint: " << res << " err " << err << endl; + + /* + //test alternative integrations + cout << endl; + cout << "dequad result of inverse bessel transform, pt=" << _qt << " m=" << _m << " y=" << _y << " : " << setprecision(16) << res << " +- " << err << endl; + hankel::init(0,0,0.1); + hankel::transform(besselint_hankel, qt, res, err); + hankel::free(); + cout << "hankel result " << res << " +- " << err << endl; + cout.precision(6); cout.unsetf(ios_base::floatfield); + + //input + int nb = 1; //lagged convolutions + int nrel = 1; //related convolutions + int ntol = 1; + int nord[1] = {0}; //order of the transform + int ijrel[2*1]; //exponents of the related convolutions (not used) + double dwork [1*801]; //work array + //output + double dans[1*1]; //result + double arg[1]; //arguments of the lagged convolutions + int nofun1; //number of function evalutions + int ierr; //error code + dhankl_(qt, nb, nrel, opts.bintaccuracy, ntol, nord, besselint_588, ijrel, dwork, dans, arg, nofun1, ierr); + res = dans[0]; + err = 0.; + cout << "588 result " << res << " +- " << err << " " << nofun1 << endl; + cout.precision(6); cout.unsetf(ios_base::floatfield); + */ - } - //Integrate up to blim with besche - else if (opts.bprescription == 1) - { - //cout << endl; - //cout << "pt " << _qt << " m " << _m << endl; - double C = blimit_.rblim_; //upper limit of integration - double ALFA[1] = {_qt}; //oscillation frequency - int NUM = 1; //number of integrals to be computed - int NU = 0; //order of the bessel function - int N = 30; //degree of the chebyshev approximation - double RESULT[1]; //output result - int INFO[1]; //output status code - besche_(besselint_besche_,C,ALFA,NUM,NU,N,RESULT,INFO); - res = RESULT[0]; - err = 0; - //cout << "besche result " << res << " status " << INFO[0] << endl; - } + } + //Integrate up to blim with besche + else if (opts.bprescription == 1) + { + //cout << endl; + //cout << "pt " << _qt << " m " << _m << endl; + double C = blimit_.rblim_; //upper limit of integration + double ALFA[1] = {_qt}; //oscillation frequency + int NUM = 1; //number of integrals to be computed + int NU = 0; //order of the bessel function + int N = 30; //degree of the chebyshev approximation + double RESULT[1]; //output result + int INFO[1]; //output status code + besche_(besselint_besche_,C,ALFA,NUM,NU,N,RESULT,INFO); + res = RESULT[0]; + err = 0; + //cout << "besche result " << res << " status " << INFO[0] << endl; + } - //Minimal prescription to avoid Landau singularity (see hep-ph/9604351 and hep-ph/0002078) - else if (opts.bprescription == 2) - { - //cout << endl; - //cout << "pt " << _qt << " m " << _m << endl; - bc = opts.bcf*blimit_.rblim_; + //Minimal prescription to avoid Landau singularity (see hep-ph/9604351 and hep-ph/0002078) + else if (opts.bprescription == 2) + { + //cout << endl; + //cout << "pt " << _qt << " m " << _m << endl; + bc = opts.bcf*blimit_.rblim_; - //besche from 0 to bc - double C = bc; //upper limit of integration - double ALFA[1] = {_qt}; //oscillation frequency - int NUM = 1; //number of integrals to be computed - int NU = 0; //order of the bessel function - int N = 30; //degree of the chebyshev approximation - double RESULT[1]; //output result - int INFO[1]; //output status code - besche_(besselint_besche_,C,ALFA,NUM,NU,N,RESULT,INFO); - res = RESULT[0]; - err = 0; - //cout << "besche result up to bc " << res << " status " << INFO[0] << endl; - - /* - double min = 0.; - double max = bc+blimit_.rblim_/_qt; - //adzint settings - double abserr = 1e-10; - double relerr = 1e-6; - double errest; - double ier; - double iacta = 0; - double iactb = 0; - - //res = 0.; - complex r = 0.; - complex i(0.,1.); + //besche from 0 to bc + double C = bc; //upper limit of integration + double ALFA[1] = {_qt}; //oscillation frequency + int NUM = 1; //number of integrals to be computed + int NU = 0; //order of the bessel function + int N = 30; //degree of the chebyshev approximation + double RESULT[1]; //output result + int INFO[1]; //output status code + besche_(besselint_besche_,C,ALFA,NUM,NU,N,RESULT,INFO); + res = RESULT[0]; + err = 0; + //cout << "besche result up to bc " << res << " status " << INFO[0] << endl; + + /* + double min = 0.; + double max = bc+blimit_.rblim_/_qt; + //adzint settings + double abserr = 1e-10; + double relerr = 1e-6; + double errest; + double ier; + double iacta = 0; + double iactb = 0; + + //res = 0.; + complex r = 0.; + complex i(0.,1.); - //upper real integral - //r += adzint_(fureal_,min,max,abserr,relerr,errest,ier,iacta,iactb); + //upper real integral + //r += adzint_(fureal_,min,max,abserr,relerr,errest,ier,iacta,iactb); - //lower real integral - //r += adzint_(fdreal_,min,max,abserr,relerr,errest,ier,iacta,iactb); + //lower real integral + //r += adzint_(fdreal_,min,max,abserr,relerr,errest,ier,iacta,iactb); - r += adzint_(freal_,min,max,abserr,relerr,errest,ier,iacta,iactb); + r += adzint_(freal_,min,max,abserr,relerr,errest,ier,iacta,iactb); - //res += real(r)/2.; - cout << "adzint result " << real(r)/2. << " error " << errest << endl; - */ + //res += real(r)/2.; + cout << "adzint result " << real(r)/2. << " error " << errest << endl; + */ - double resdequad; - double errdequad; - - /* - complex r = 0.; - intdeo(frealu_dequad, 0, qt*cos(M_PI/opts.phibr), awinf, &resdequad, &errdequad); - r += resdequad; - cout << "dequad up result " << resdequad << " error " << errdequad << endl; - - intdeo(freald_dequad, 0, qt*cos(M_PI/opts.phibr), awinf, &resdequad, &errdequad); - r += resdequad; - cout << "dequad dn result " << resdequad << " error " << errdequad << endl; - - res += real(r)/2.; - cout << "Split dequad result " << real(r)/2. << " error " << errdequad << endl; - */ + double resdequad; + double errdequad; - intdeo(besselint_mp_complex_dequad, 0, qt*cos(M_PI/opts.phibr), awinf, &resdequad, &errdequad); - //cout << "Complex dequad result " << resdequad << " error " << errdequad << endl; - res += resdequad; - - //cout << "Total bp = 2 " << res << endl; - } - //Minimal prescription along the real axis, crossing the Landau singularity - else if (opts.bprescription == 3) - { - //minimal prescription with real b integration (not always more efficient, but save the calculation of PDFs at complex scales) - - bc = opts.bcf*blimit_.rblim_; - - //besche from 0 to bc - double C = bc; //upper limit of integration - double ALFA[1] = {_qt}; //oscillation frequency - int NUM = 1; //number of integrals to be computed - int NU = 0; //order of the bessel function - int N = 30; //degree of the chebyshev approximation - double RESULT[1]; //output result - int INFO[1]; //output status code - besche_(besselint_besche_,C,ALFA,NUM,NU,N,RESULT,INFO); - res = RESULT[0]; - err = 0; - - double resdequad; - double errdequad; - intdeo(besselint_mp_real_dequad, 0, qt, awinf, &resdequad, &errdequad); - cout << "Real dequad result " << resdequad << " error " << errdequad << endl; - res += resdequad; - - cout << "Total bp = 3 " << res << endl; - } + /* + complex r = 0.; + intdeo(frealu_dequad, 0, qt*cos(M_PI/opts.phibr), awinf, &resdequad, &errdequad); + r += resdequad; + cout << "dequad up result " << resdequad << " error " << errdequad << endl; + + intdeo(freald_dequad, 0, qt*cos(M_PI/opts.phibr), awinf, &resdequad, &errdequad); + r += resdequad; + cout << "dequad dn result " << resdequad << " error " << errdequad << endl; + + res += real(r)/2.; + cout << "Split dequad result " << real(r)/2. << " error " << errdequad << endl; + */ + + intdeo(besselint_mp_complex_dequad, 0, qt*cos(M_PI/opts.phibr), awinf, &resdequad, &errdequad); + //cout << "Complex dequad result " << resdequad << " error " << errdequad << endl; + res += resdequad; + //cout << "Total bp = 2 " << res << endl; } - else + //Minimal prescription along the real axis, crossing the Landau singularity + else if (opts.bprescription == 3) { - //split the integral above and below the b and c masses - - //scale b0/b without a_param - double bstar_mb = resconst::b0/(LHAPDF::getThreshold(5)*opts.kmub); - //convert bstar to b - double b_mb = bstar_mb / sqrt(1-(bstar_mb*bstar_mb)/(blimit_.rblim_*blimit_.rblim_)); - - //same for charm mass - double bstar_mc = resconst::b0/(LHAPDF::getThreshold(4)*opts.kmuc); - double b_mc = bstar_mc / sqrt(1-(bstar_mc*bstar_mc)/(blimit_.rblim_*blimit_.rblim_)); - - //Integrate from pt=0 to pt=mc (from b_mc to infinity) - //Set NF = 3 - sudakov::setnf(3); - double res1, err1; - //intdeo(besselint::bint, b_mc, qt, awinf, &res1, &err1); - intdeo(besselint_dequad, b_mc, qt, awinf, &res1, &err1); - - - //Integrate from pt=mb to pt=infinity (from 0 to b_mb) - //Set NF = 5 - sudakov::setnf(5); - double res2, err2; - //dequad seems not to be appropriate for this integral - // intde(besselint::bint, 0.0, b_mb, awfin, &res2, &err2); - - //try simple pcubature - const int ndim = 1; //dimensions of the integral - const int ncomp = 1; //components of the integrand - void *userdata = NULL; - double integral[1]; - double error[1]; - const int eval = 0; - const double epsrel = 1e-2;//opts.bintaccuracy; - const double epsabs = 0.; - double xmin[1] = {0.000001}; - double xmax[1] = {b_mb}; - /* - pcubature(ncomp, besselint_cubature, userdata, - ndim, xmin, xmax, - eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); - res2 = integral[0]; - err2 = error[0]; - cout << endl; - cout << "pcubature result " << res2 << " error " << err2 << endl; - */ - - double C = b_mb; //upper limit of integration + //minimal prescription with real b integration (not always more efficient, but save the calculation of PDFs at complex scales) + + bc = opts.bcf*blimit_.rblim_; + + //besche from 0 to bc + double C = bc; //upper limit of integration double ALFA[1] = {_qt}; //oscillation frequency int NUM = 1; //number of integrals to be computed int NU = 0; //order of the bessel function int N = 30; //degree of the chebyshev approximation double RESULT[1]; //output result int INFO[1]; //output status code besche_(besselint_besche_,C,ALFA,NUM,NU,N,RESULT,INFO); - res2 = RESULT[0]; - err2 = 0; - - //cout << "besche result " << res2 << " status " << INFO[0] << endl; + res = RESULT[0]; + err = 0; + + double resdequad; + double errdequad; + intdeo(besselint_mp_real_dequad, 0, qt, awinf, &resdequad, &errdequad); + cout << "Real dequad result " << resdequad << " error " << errdequad << endl; + res += resdequad; - //Integrate from pt=mc to pt=mb (from b_mb to b_mc) - //Set NF = 4 - sudakov::setnf(4); - double res3, err3; - xmin[0] = {b_mb}; - xmax[0] = {b_mc}; - pcubature(ncomp, besselint_cubature, userdata, - ndim, xmin, xmax, - eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); - res3 = integral[0]; - err3 = error[0]; + cout << "Total bp = 3 " << res << endl; + } - res = res1+res2+res3; + // //vfn integration --> Not correct!!! + // //split the integral above and below the b and c masses + // + // //scale b0/b without a_param + // double bstar_mb = resconst::b0/(LHAPDF::getThreshold(5)*opts.kmub); + // //convert bstar to b + // double b_mb = bstar_mb / sqrt(1-(bstar_mb*bstar_mb)/(blimit_.rblim_*blimit_.rblim_)); + // + // //same for charm mass + // double bstar_mc = resconst::b0/(LHAPDF::getThreshold(4)*opts.kmuc); + // double b_mc = bstar_mc / sqrt(1-(bstar_mc*bstar_mc)/(blimit_.rblim_*blimit_.rblim_)); + // + // //Integrate from pt=0 to pt=mc (from b_mc to infinity) + // //Set NF = 3 + // sudakov::setnf(3); + // double res1, err1; + // //intdeo(besselint::bint, b_mc, qt, awinf, &res1, &err1); + // intdeo(besselint_dequad, b_mc, qt, awinf, &res1, &err1); + // + // + // //Integrate from pt=mb to pt=infinity (from 0 to b_mb) + // //Set NF = 5 + // sudakov::setnf(5); + // double res2, err2; + // //dequad seems not to be appropriate for this integral + // // intde(besselint::bint, 0.0, b_mb, awfin, &res2, &err2); + // + // //try simple pcubature + // const int ndim = 1; //dimensions of the integral + // const int ncomp = 1; //components of the integrand + // void *userdata = NULL; + // double integral[1]; + // double error[1]; + // const int eval = 0; + // const double epsrel = 1e-2;//opts.bintaccuracy; + // const double epsabs = 0.; + // double xmin[1] = {0.000001}; + // double xmax[1] = {b_mb}; + // /* + // pcubature(ncomp, besselint_cubature, userdata, + // ndim, xmin, xmax, + // eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); + // res2 = integral[0]; + // err2 = error[0]; + // cout << endl; + // cout << "pcubature result " << res2 << " error " << err2 << endl; + // */ + // + // double C = b_mb; //upper limit of integration + // double ALFA[1] = {_qt}; //oscillation frequency + // int NUM = 1; //number of integrals to be computed + // int NU = 0; //order of the bessel function + // int N = 30; //degree of the chebyshev approximation + // double RESULT[1]; //output result + // int INFO[1]; //output status code + // besche_(besselint_besche_,C,ALFA,NUM,NU,N,RESULT,INFO); + // res2 = RESULT[0]; + // err2 = 0; + // + // //cout << "besche result " << res2 << " status " << INFO[0] << endl; + // + // //Integrate from pt=mc to pt=mb (from b_mb to b_mc) + // //Set NF = 4 + // sudakov::setnf(4); + // double res3, err3; + // xmin[0] = {b_mb}; + // xmax[0] = {b_mc}; + // pcubature(ncomp, besselint_cubature, userdata, + // ndim, xmin, xmax, + // eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); + // res3 = integral[0]; + // err3 = error[0]; + // + // res = res1+res2+res3; + // + // /* + // cout << "split: dequad result of inverse bessel transform, " << endl; + // cout << "total: " + // //<< setprecision(16) + // << res << " " << (err1+err2+err3)/res*100 << endl; + // cout << " b(mc)-inf: " << res1 << " " << err1/res1*100 << "%" + // << " 0-b(mb): " << res2 << " " << err2/res2*100 << "%" + // << " b(mb)-b(mc): " << res3 << " " << err3/res3*100 << "%" + // << endl; + // //cout.precision(6); cout.unsetf(ios_base::floatfield); + // //cout << "b_mb " << b_mb << " b_mc " << b_mc << " blim " << blimit_.rblim_ << endl; + // cout << endl; + // */ - /* - cout << "split: dequad result of inverse bessel transform, " << endl; - cout << "total: " - //<< setprecision(16) - << res << " " << (err1+err2+err3)/res*100 << endl; - cout << " b(mc)-inf: " << res1 << " " << err1/res1*100 << "%" - << " 0-b(mb): " << res2 << " " << err2/res2*100 << "%" - << " b(mb)-b(mc): " << res3 << " " << err3/res3*100 << "%" - << endl; - //cout.precision(6); cout.unsetf(ios_base::floatfield); - //cout << "b_mb " << b_mb << " b_mc " << b_mc << " blim " << blimit_.rblim_ << endl; - cout << endl; - */ - - } /* //plot the b-integrand cout << "{" << endl; cout << "TGraph *g = new TGraph();" << endl; for (int i = 0; i < 1000; i++) { // double b = b_mb*0.95+i*(b_mb*1.05 -b_mb*0.95)/100.; double b = 0.+i*(b_mb*5 -0)/1000.; // cout << b << " " << b_mb << " " << besselint::bint(b) << endl;; cout << "g->SetPoint(g->GetN(), " << b << ", " << besselint::bint(b) << ");" << endl; } cout << "g->Draw();" << endl; cout << "}" << endl; */ return res; } diff --git a/scripts/download_grid.sh b/scripts/download_grid.sh index 8f47a58..367d35d 100755 --- a/scripts/download_grid.sh +++ b/scripts/download_grid.sh @@ -1,31 +1,34 @@ #!/bin/bash if [[ -z $1 ]] then echo "usage: $0 " exit fi jid=$1 mkdir -p out cd out -rucio download user.${USER}.${jid}.*.results.root download user.${USER}.${jid}.'*'.results.txt user.${USER}.'*'.${jid}.*.log.tgz +rucio download user.${USER}.${jid}.*.results.root +rucio download user.${USER}.${jid}.'*'.results.txt +rucio download user.${USER}.'*'.${jid}.*.log.tgz tag=`cd user.${USER}; ls *.tgz |cut -d . -f3 |uniq` + mkdir -p $tag/root mkdir -p $tag/txt mkdir -p $tag/log -mv user.${USER}/*.root $tag/root -mv user.${USER}/*.txt $tag/txt -mv user.${USER}/*.tgz $tag/log +mv user.${USER}/*${jid}*.root $tag/root +mv user.${USER}/*${jid}*.txt $tag/txt +mv user.${USER}/*${jid}*.tgz $tag/log rmdir user.${USER} cd $tag/log for file in `ls *.tgz` do tar -xzf $file rm $file done diff --git a/src/abint.C b/src/abint.C index bec42bb..b482e8f 100644 --- a/src/abint.C +++ b/src/abint.C @@ -1,43 +1,49 @@ #include "abint.h" #include "gaussrules.h" #include "settings.h" #include double *abint::abx; double *abint::abw; int abint::abdim; void abint::init() { //initialize the points of the gaussian quadrature for the alfa and beta integration abdim = opts.abintervals*opts.abrule; abx = new double [abdim]; abw = new double [abdim]; double min = 1e-7; double max = 1.; double lmm = log(max/min); for (int i = 0; i < opts.abintervals; i++) { double a = 0.+(1.-0.)*i/opts.abintervals; double b = 0.+(1.-0.)*(i+1)/opts.abintervals; double c = 0.5*(a+b); double m = 0.5*(b-a); for (int j = 0; j < opts.abrule; j++) { //with change of variable t = eps^(1-x), and with lower cutoff eps on z1 z2 double x = c+m*gr::xxx[opts.abrule-1][j]; double t = min*pow(max/min,x); double jac=t*lmm; abx[j+i*opts.abrule]=t; abw[j+i*opts.abrule]=gr::www[opts.abrule-1][j]*m*jac; //without change of variable, and without lower cutoff on z1 z2 //abx[j+i*opts.abrule]=c+m*gr::xxx[opts.abrule-1][j]; //abw[j+i*opts.abrule]=gr::www[opts.abrule-1][j]*m; } } } +void abint::release() +{ + delete[] abx; + delete[] abw; + +} diff --git a/src/abint.h b/src/abint.h index 77a925b..027a698 100644 --- a/src/abint.h +++ b/src/abint.h @@ -1,13 +1,14 @@ #ifndef abint_h #define abint_h namespace abint { extern double *abx; extern double *abw; extern int abdim; void init(); + void release(); } #endif diff --git a/src/clenshawcurtisrules.C b/src/clenshawcurtisrules.C index e37f0e0..25b4030 100644 --- a/src/clenshawcurtisrules.C +++ b/src/clenshawcurtisrules.C @@ -1,394 +1,398 @@ #include "clenshawcurtisrules.h" //nodes and weights for the Clenshaw Curtis quadrature rules //from https://people.sc.fsu.edu/~jburkardt/datasets/quadrature_rules_clenshaw_curtis/quadrature_rules_clenshaw_curtis.html #include "sandia_rules.hpp" #include "settings.h" #include #include #include using namespace std; double cc::xxx[65][65]; double cc::www[65][65]; double cc::cosw[65][65]; double cc::sinw[65][65]; const double cc::xxx9[9]={-1.0000000000000000, -0.9238795325112867, -0.7071067811865475, -0.3826834323650897, 0.000000000000000, 0.3826834323650898, 0.7071067811865475, 0.9238795325112867, 1.0000000000000000}; const double cc::www9[9]={0.1587301587301588E-01, 0.1462186492160182, 0.2793650793650794, 0.3617178587204897, 0.3936507936507936, 0.3617178587204898, 0.2793650793650794, 0.1462186492160182, 0.1587301587301588E-01}; const double cc::xxx33[33]={-1.0000000000000000, -0.9951847266721968, -0.9807852804032304, -0.9569403357322088, -0.9238795325112867, -0.8819212643483549, -0.8314696123025453, -0.7730104533627370, -0.7071067811865475, -0.6343932841636454, -0.5555702330196020, -0.4713967368259977, -0.3826834323650897, -0.2902846772544622, -0.1950903220161282, -0.9801714032956065E-01, 0.000000000000000, 0.9801714032956077E-01, 0.1950903220161283, 0.2902846772544623, 0.3826834323650898, 0.4713967368259978, 0.5555702330196023, 0.6343932841636455, 0.7071067811865475, 0.7730104533627370, 0.8314696123025452, 0.8819212643483550, 0.9238795325112867, 0.9569403357322088, 0.9807852804032304, 0.9951847266721969, 1.0000000000000000}; const double cc::www33[33]={0.9775171065493659E-03, 0.9393197962955013E-02, 0.1923424513268114E-01, 0.2845791667723369E-01, 0.3759434191404722E-01, 0.4626276283775175E-01, 0.5455501630398032E-01, 0.6227210954529399E-01, 0.6942757563043547E-01, 0.7588380044138848E-01, 0.8163481765493850E-01, 0.8657753844182743E-01, 0.9070611286772098E-01, 0.9394324443876872E-01, 0.9629232594548820E-01, 0.9769818820805558E-01, 0.9817857778176831E-01, 0.9769818820805558E-01, 0.9629232594548819E-01, 0.9394324443876871E-01, 0.9070611286772098E-01, 0.8657753844182743E-01, 0.8163481765493850E-01, 0.7588380044138850E-01, 0.6942757563043547E-01, 0.6227210954529399E-01, 0.5455501630398031E-01, 0.4626276283775177E-01, 0.3759434191404721E-01, 0.2845791667723370E-01, 0.1923424513268119E-01, 0.9393197962955048E-02, 0.9775171065493659E-03}; const double cc::xxx65[65]={-1.0000000000000000, -0.9987954562051724, -0.9951847266721968, -0.9891765099647810, -0.9807852804032304, -0.9700312531945440, -0.9569403357322088, -0.9415440651830207, -0.9238795325112867, -0.9039892931234433, -0.8819212643483549, -0.8577286100002720, -0.8314696123025453, -0.8032075314806448, -0.7730104533627370, -0.7409511253549589, -0.7071067811865475, -0.6715589548470184, -0.6343932841636454, -0.5956993044924334, -0.5555702330196020, -0.5141027441932217, -0.4713967368259977, -0.4275550934302819, -0.3826834323650897, -0.3368898533922199, -0.2902846772544622, -0.2429801799032639, -0.1950903220161282, -0.1467304744553616, -0.9801714032956065E-01, -0.4906767432741801E-01, 0.000000000000000, 0.4906767432741813E-01, 0.9801714032956077E-01, 0.1467304744553617, 0.1950903220161283, 0.2429801799032640, 0.2902846772544623, 0.3368898533922201, 0.3826834323650898, 0.4275550934302822, 0.4713967368259978, 0.5141027441932218, 0.5555702330196023, 0.5956993044924335, 0.6343932841636455, 0.6715589548470184, 0.7071067811865475, 0.7409511253549592, 0.7730104533627370, 0.8032075314806448, 0.8314696123025452, 0.8577286100002721, 0.8819212643483550, 0.9039892931234433, 0.9238795325112867, 0.9415440651830208, 0.9569403357322088, 0.9700312531945440, 0.9807852804032304, 0.9891765099647810, 0.9951847266721969, 0.9987954562051724, 1.0000000000000000}; const double cc::www65[65]={0.2442002442002449E-03, 0.2351490675311702E-02, 0.4831465448790911E-02, 0.7192693161736115E-02, 0.9582338795283791E-02, 0.1192339471421277E-01, 0.1425206043235199E-01, 0.1653498765728959E-01, 0.1878652974179578E-01, 0.2098627442973744E-01, 0.2314069493435819E-01, 0.2523506498175476E-01, 0.2727225714146840E-01, 0.2924065319746835E-01, 0.3114129710406762E-01, 0.3296454656997634E-01, 0.3471049818092511E-01, 0.3637092028663919E-01, 0.3794545992128482E-01, 0.3942698871295609E-01, 0.4081501340035782E-01, 0.4210333111141810E-01, 0.4329151496169082E-01, 0.4437417923925731E-01, 0.4535110955166067E-01, 0.4621766751092559E-01, 0.4697395904661415E-01, 0.4761604458525018E-01, 0.4814443257251221E-01, 0.4855584485714105E-01, 0.4885125664306610E-01, 0.4902801843102554E-01, 0.4908762351494248E-01, 0.4902801843102556E-01, 0.4885125664306610E-01, 0.4855584485714105E-01, 0.4814443257251221E-01, 0.4761604458525019E-01, 0.4697395904661414E-01, 0.4621766751092559E-01, 0.4535110955166067E-01, 0.4437417923925733E-01, 0.4329151496169082E-01, 0.4210333111141811E-01, 0.4081501340035782E-01, 0.3942698871295609E-01, 0.3794545992128483E-01, 0.3637092028663919E-01, 0.3471049818092511E-01, 0.3296454656997635E-01, 0.3114129710406762E-01, 0.2924065319746836E-01, 0.2727225714146839E-01, 0.2523506498175477E-01, 0.2314069493435821E-01, 0.2098627442973743E-01, 0.1878652974179578E-01, 0.1653498765728961E-01, 0.1425206043235200E-01, 0.1192339471421278E-01, 0.9582338795283809E-02, 0.7192693161736120E-02, 0.4831465448790926E-02, 0.2351490675311698E-02, 0.2442002442002449E-03}; void cc::init() { for (int i = 0; i < 65; i++) for (int j = 0; j < 65; j++) { xxx[i][j] = 0; www[i][j] = 0; } for (int i = 0; i < 65; i++) { if (i < 9) xxx[9-1][i] = xxx9[i]; if (i < 33) xxx[33-1][i] = xxx33[i]; if (i < 65) xxx[65-1][i] = xxx65[i]; if (i < 9) www[9-1][i] = www9[i]; if (i < 33) www[33-1][i] = www33[i]; if (i < 65) www[65-1][i] = www65[i]; } //generation of weights and nodes for (int n = 1; n <= 65; n++) { double *w = new double[n]; double *x = new double[n]; webbur::clenshaw_curtis_compute(n, x, w); for ( int i = 1; i <= n; i++ ) { xxx[n-1][i-1] = x[i-1]; www[n-1][i-1] = w[i-1]; } + delete[] w; + delete[] x; } /* //calculate nodes and weights and cross check result int n = opts.mellinrule; int N = n-1; { double *w = new double[n]; double *x = new double[n]; webbur::clenshaw_curtis_compute(n, x, w); for ( int j = 0; j <= N; j++ ) { cout << "cc nodes and weights: " << j << " " << x[j] << " " << w[j] << endl; //calculate double x = cos(M_PI*double(N-j)/double(N)); double sumjk = 0; for ( int k = 0; k <= N; k++ ) { double jktk; if (k == 1) jktk = 0.; else if (k == 0 || k == N) jktk = (-cos(M_PI*k)-1.)/(pow(k,2) - 1)/2.*cos(k*M_PI*j/double(N)); else jktk = (-cos(M_PI*k)-1.)/(pow(k,2) - 1)*cos(k*M_PI*j/double(N)); sumjk += jktk; } double w = 2./double(N) * sumjk; if (j == 0 || j == N) w/= 2.; cout << "calc nodes and weights: " << j << " " << x << " " << w << endl; } } cout << endl; setw(1e-2); */ } //tabulate jkcoswx = int_0^pi cos(k*t)*cos(w*cos(t))*sin(t) dt double jkcoswx(int k, double W) { __float128 res; __float128 w = W; if (k%2 == 1) return 0.; if (k == 0) res = 2*sinq(w)/w; if (k == 2) res = 2*(4*w*cosq(w) + (powq(w,2) - 4)*sinq(w))/powq(w,3); if (k == 4) res = 2*(16*(powq(w,3) - 12*w)*cosq(w) + (powq(w,4) - 80*powq(w,2) + 192)*sinq(w))/powq(w,5); if (k == 6) res = 2*(12*(3*powq(w,5) - 224*powq(w,3) + 1920*w)*cosq(w) + (powq(w,6) - 420*powq(w,4) + 10368*powq(w,2) - 23040)*sinq(w))/powq(w,7); if (k == 8) res = 2.Q*(64.Q*(powq(w,7) - 252.Q*powq(w,5) + 10560.Q*powq(w,3) - 80640.Q*w)*cosq(w) + (powq(w,8) - 1344.Q*powq(w,6) + 126720.Q*powq(w,4) - 2396160.Q*powq(w,2) + 5160960.Q)*sinq(w))/powq(w,9); if (k == 10) res = 2.Q*(20.Q*(5.Q*powq(w,9) - 3168.Q*powq(w,7) + 384384.Q*powq(w,5) - 12902400.Q*powq(w,3) + 92897280.Q*w)*cosq(w) + (powq(w,10) - 3300.Q*powq(w,8) + 823680.Q*powq(w,6) - 52416000.Q*powq(w,4) + 877363200.Q*powq(w,2) - 1857945600.Q)*sinq(w))/powq(w,11); if (k == 12) res = 2.Q*(48.Q*(3.Q*powq(w,11) - 4004.Q*powq(w,9) + 1098240.Q*powq(w,7) - 98703360.Q*powq(w,5) + 2941747200.Q*powq(w,3) - 20437401600.Q*w)*cosq(w) + (powq(w,12) - 6864.Q*powq(w,10) + 3706560.Q*powq(w,8) - 570286080.Q*powq(w,6) + 30005821440.Q*powq(w,4) - 468202291200.Q*powq(w,2) + 980995276800.Q)*sinq(w))/powq(w,13); if (k == 14) res = 2.Q*(28.Q*(7.Q*powq(w,13) - 17472.Q*powq(w,11) + 9335040.Q*powq(w,9) - 1786060800.Q*powq(w,7) + 135908720640.Q*powq(w,5) - 3760481894400.Q*powq(w,3) + 25505877196800.Q*w)*cosq(w) + (powq(w,14) - 12740.Q*powq(w,12) + 13069056.Q*powq(w,10) - 4063288320.Q*powq(w,8) + 490095083520.Q*powq(w,6) - 23032951603200.Q*powq(w,4) + 343348346880000.Q*powq(w,2) - 714164561510400.Q)*sinq(w))/powq(w,15); if (k == 16) res = 2*(256*(powq(w,15) - 4284*powq(w,13) + 4031040*powq(w,11) - 1432569600*powq(w,9) + 223278612480*powq(w,7) - 15276957696000*powq(w,5) + 401717565849600*powq(w,3) - 2678117105664000*w)*cosq(w) + (powq(w,16) - 21760*powq(w,14) + 38697984*powq(w,12) - 21670871040*powq(w,10) + 5060981882880*powq(w,8) - 526467465216000*powq(w,6) + 22955289477120000*powq(w,4) - 331372356540825600*powq(w,2) + 685597979049984000)*sinq(w))/powq(w,17); if (k == 18) res = 2*(108*(3*powq(w,17) - 20672.Q*powq(w,15) + 31834880.Q*powq(w,13) - 19170385920.Q*powq(w,11) + 5375225856000.Q*powq(w,9) - 733293969408000.Q*powq(w,7) + 46599237638553600.Q*powq(w,5) - 1180752075030528000.Q*powq(w,3) + 7770110429233152000.Q*w)*cosq(w) + (powq(w,18) - 34884.Q*powq(w,16) + 100465920.Q*powq(w,14) - 93455631360.Q*powq(w,12) + 37957364121600.Q*powq(w,10) - 7424601440256000.Q*powq(w,8) + 698988564578304000.Q*powq(w,6) - 28891527335903232000.Q*powq(w,4) + 407245199555690496000.Q*powq(w,2) - 839171926357180416000.Q)*sinq(w))/powq(w,19); if (k == 20) res = 2.Q*(80.Q*(5.Q*powq(w,19) - 52668.Q*powq(w,17) + 125520384.Q*powq(w,15) - 119814912000.Q*powq(w,13) + 55413692006400.Q*powq(w,11) - 13290953195520000.Q*powq(w,9) + 1650944419194470400.Q*powq(w,7) - 99360287113818931200.Q*powq(w,5) + 2447584785208442880000.Q*powq(w,3) - 15944266600786427904000.Q*w)*cosq(w) + (powq(w,20) - 53200.Q*powq(w,18) + 235350720.Q*powq(w,16) - 342328320000.Q*powq(w,14) + 224293515264000.Q*powq(w,12) - 74429337894912000.Q*powq(w,10) + 12898003274956800000.Q*powq(w,8) - 1129979735804215296000.Q*powq(w,6) + 44872387728821452800000.Q*powq(w,4) - 620987225504313507840000.Q*powq(w,2) + 1275541328062914232320000.Q)*sinq(w))/powq(w,21); double val = res; //cout << val << endl; return val; } //tabulate jksinwx = int_0^pi cos(k*t)*sin(w*cos(t))*sin(t) dt double jksinwx(int k, double W) { __float128 res; __float128 w = W; if (k%2 == 0) return 0.; if (k == 1) res = -2*(w*cosq(w) - sinq(w))/powq(w,2); if (k == 3) res = -2*((powq(w,3) - 24*w)*cosq(w) - 3*(3*powq(w,2) - 8)*sinq(w))/powq(w,4); if (k == 5) res = -2*((powq(w,5) - 200*powq(w,3) + 1920*w)*cosq(w) - 5*(5*powq(w,4) - 168*powq(w,2) + 384)*sinq(w))/powq(w,6); if (k == 7) res = -2*((powq(w,7) - 784*powq(w,5) + 40320*powq(w,3) - 322560*w)*cosq(w) - 7*(7*powq(w,6) - 1008*powq(w,4) + 21120*powq(w,2) - 46080)*sinq(w))/powq(w,8); if (k == 9) res = -2.Q*((powq(w,9) - 2160.Q*powq(w,7) + 342144.Q*powq(w,5) - 12579840.Q*powq(w,3) + 92897280.Q*w)*cosq(w) - 27.Q*(3.Q*powq(w,8) - 1232.Q*powq(w,6) + 91520.Q*powq(w,4) - 1612800.Q*powq(w,2) + 3440640.Q)*sinq(w))/powq(w,10); if (k == 11) res = -2.Q*((powq(w,11) - 4840.Q*powq(w,9) + 1812096.Q*powq(w,7) - 184504320.Q*powq(w,5) + 5790597120.Q*powq(w,3) - 40874803200.Q*w)*cosq(w) - 11.Q*(11.Q*powq(w,10) - 10296.Q*powq(w,8) + 1921920.Q*powq(w,6) - 109670400.Q*powq(w,4) + 1765048320.Q*powq(w,2) - 3715891200.Q)*sinq(w))/powq(w,12); if (k == 13) res = -2.Q*((powq(w,13) - 9464.Q*powq(w,11) + 7138560.Q*powq(w,9) - 1588654080.Q*powq(w,7) + 130025226240.Q*powq(w,5) - 3719607091200.Q*powq(w,3) + 25505877196800.Q*w)*cosq(w) - 13.Q*(13.Q*powq(w,12) - 24024.Q*powq(w,10) + 9335040.Q*powq(w,8) - 1250242560.Q*powq(w,6) + 61776691200.Q*powq(w,4) - 940120473600.Q*powq(w,2) + 1961990553600.Q)*sinq(w))/powq(w,14); if (k == 15) res = -2*((powq(w,15) - 16800*powq(w,13) + 22913280*powq(w,11) - 9674496000*powq(w,9) + 1650320179200*powq(w,7) - 118455179673600*powq(w,5) + 3188234649600000*powq(w,3) - 21424936845312000*w)*cosq(w) - 15*(15*powq(w,14) - 49504*powq(w,12) + 35473152*powq(w,10) - 9376819200*powq(w,8) + 1041966858240*powq(w,6) - 47006023680000*powq(w,4) + 688658684313600*powq(w,2) - 1428329123020800)*sinq(w))/powq(w,16); //if (k == 17) res = -2*((powq(w,17) - 27744*powq(w,15) + 63256320*powq(w,13) - 46050600960*powq(w,11) + 14339448668160*powq(w,9) - 2077666246656000*powq(w,7) + 136583972388864000*powq(w,5) - 3520831288246272000*powq(w,3) + 23310331287699456000ULL*w)*cosq(w) - 17*(17*powq(w,16) - 93024*powq(w,14) + 112869120*powq(w,12) - 52718561280*powq(w,10) + 11163930624000*powq(w,8) - 1099940954112000*powq(w,6) + 46599237638553600*powq(w,4) - 664173042204672000*powq(w,2) + 1371195958099968000)*sinq(w))/powq(w,18); // if (k == 19) res = -2*((powq(w,19) - 43320*powq(w,17) + 155536128*powq(w,15) - 182118666240*powq(w,13) + 94701706444800*powq(w,11) - 24382024482816000*powq(w,9) + 3162091125473280000*powq(w,7) - 195178318002546278400*powq(w,5) + 4871859239129186304000*powq(w,3) - 31888533201572855808000*w)*cosq(w) - 19*(19*powq(w,18) - 162792*powq(w,16) + 313800960*powq(w,14) - 239629824000*powq(w,12) + 87078658867200*powq(w,10) - 15949143834624000*powq(w,8) + 1444576366795161600*powq(w,6) - 58447227714011136000*powq(w,4) + 815861595069480960000*powq(w,2) - 1678343852714360832000)*sinq(w))/powq(w,20); double val = res; return val; } void cc::setw(double omega) { //calculate nodes and weights with w(x) = cos(x) and w(x) = sin(x) int n = opts.mellinrule; int N = n-1; { - double *w = new double[n]; - double *x = new double[n]; - webbur::clenshaw_curtis_compute(n, x, w); + //double *w = new double[n]; + //double *x = new double[n]; + //webbur::clenshaw_curtis_compute(n, x, w); for ( int j = 0; j <= N; j++ ) { // cout << "cc nodes and weights: " << j << " " << x[j] << " " << w[j] << endl; double sumjkcosw = 0; double sumjksinw = 0; for ( int k = 0; k <= N; k++ ) { double jktk; if (k == 0 || k == N) jktk = jkcoswx(k,omega)/2.*cos(k*M_PI*j/double(N)); else jktk = jkcoswx(k,omega)*cos(k*M_PI*j/double(N)); sumjkcosw += jktk; if (k == 0 || k == N) jktk = jksinwx(k,omega)/2.*cos(k*M_PI*j/double(N)); else jktk = jksinwx(k,omega)*cos(k*M_PI*j/double(N)); sumjksinw += jktk; } cosw[N][j] = 2./double(N) * sumjkcosw; if (j == 0 || j == N) cosw[N][j]/= 2.; sinw[N][j] = 2./double(N) * sumjksinw; if (j == 0 || j == N) sinw[N][j]/= 2.; // cout << "calc nodes and weights: " << j << " " << x[j] << " " << cosw[N][j] << " " << sinw[N][j] << endl; } + //delete[] w; + //delete[] x; } } diff --git a/src/ctintegr.C b/src/ctintegr.C index 4660fc1..3b23ba7 100644 --- a/src/ctintegr.C +++ b/src/ctintegr.C @@ -1,655 +1,656 @@ #include "ctintegr.h" #include "dyres_interface.h" #include "interface.h" #include "omegaintegr.h" #include "phasespace.h" #include "settings.h" #include "switch.h" #include "cubacall.h" #include "isnan.h" #include "qtint.h" #include "ctint.h" #include "ctmellin.h" #include "KinematicCuts.h" #include #include #include #include //Upper limit of integration in qt (in dynnlo it is set to qtcut**2*exp(49) ~ 1e21) const double ctlimit = 1e10; using namespace std; integrand_t ctintegrand(const int &ndim, const double x[], const int &ncomp, double f[], void* userdata, const int &nvec, const int &core, double &weight, const int &iter) { tell_to_grid_we_are_alive(); //here generate the phase space according to x[], and pass the p vector to countint_ if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = 0.; double rct[22]; for (int i = 0; i < ndim; i++) rct[i]=x[i]; rct[8] = rct[1]; dofill_.doFill_ = int(iter==last_iter); f[0] = countint_(rct,weight,f); return 0; } integrand_t ctintegrandMC(const int &ndim, const double x[], const int &ncomp, double f[], void* userdata, const int &nvec, const int &core, double &weight, const int &iter) { tell_to_grid_we_are_alive(); clock_t begin_time, end_time; begin_time = clock(); if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = 0.; if (opts.fixedorder && phasespace::qtmin > 0) { f[0]=0.; return 0; } //Jacobian of the change of variables from the unitary hypercube x[6] to the m, y, qt, phi, costh, philep boundaries double jac = 1.; bool status = true; double r1[2] = {x[0], x[1]}; status = phasespace::gen_my(r1, jac, true, !opts.fixedorder); //qtcut = true, qtswitching = true if (!status) { f[0] = 0.; return 0; } double qt; //In the fixed order calculation, integrate from qtcut to infinity if (opts.fixedorder) { phasespace::gen_qt_ctfo(x[2], jac); qt = phasespace::qt; phasespace::set_qt(0.); //In the fixed order calculation evaluate kinematic cuts with qt=0 } else { //Generate the boson transverse momentum between the integration boundaries double qtcut = max(opts.qtcut,opts.xqtcut*phasespace::m); double qtmn = max(qtcut, phasespace::qtmin); //phasespace::calcexpy(); //double cosh2y=pow((phasespace::exppy+phasespace::expmy)*0.5,2); //double kinqtlim = sqrt(max(0.,pow(pow(opts.sroot,2)+phasespace::m2,2)/(4*pow(opts.sroot,2)*cosh2y)-phasespace::m2)); //introduced max to avoid neqative argument of sqrt when y=ymax //double kinqtlim = sqrt(max(0.,pow(pow(opts.sroot,2)+phasespace::m2,2)/(4*pow(opts.sroot,2))-phasespace::m2)); //introduced max to avoid negative argument of sqrt when y=ymax double kinqtlim = ctlimit; //There should not be any kinematic limit on qt, since the counterterm is evaluated with born level kinematic double switchqtlim = switching::qtlimit(phasespace::m); double qtlim = min(kinqtlim, switchqtlim); double qtmx = min(qtlim, phasespace::qtmax); if (qtmn >= qtmx) { f[0] = 0.; return 0; } status = phasespace::gen_qt(x[2], jac, qtlim, true); if (!status) { f[0] = 0.; return 0; } qt = phasespace::qt; } jac = jac *2.*qt; //generate boson 4-momentum, with m, qt, y, and phi phasespace::set_phiV(-M_PI+2.*M_PI*x[5]); ///////////////////// //This function set the RF axes according to the selected qt-recoil prescription omegaintegr::genV4p(); //alternative, generate in naive RF, and calculate costh with the selected qt-recoil prescription //phasespace::genRFaxes(phasespace::naive); //phasespace::genV4p(); ///////////////////// double r2[2] = {x[3], x[4]}; phasespace::gen_costhphi(r2, jac); + phasespace::calcphilep(); phasespace::genl4p(); //apply lepton cuts if (opts.makecuts) if (!Kinematics::Cuts::KeepThisEvent(phasespace::p3, phasespace::p4)) { f[0]=0.; return 0; } ///////////////////// double costh_CS = phasespace::costh; //alternative, generate in naive RF, and calculate costh with the selected qt-recoil prescription //double costh_CS = omegaintegr::costh_qtrec(); //cout << phasespace::costh << " " << costh_CS << endl; ///////////////////// double m = phasespace::m; double y = phasespace::y; jac = jac/2./M_PI; //apply resummation switching double swtch = switching::swtch(qt, m); /* //No need to check the switching, since the phase space is generated up to the switching qt limit if (swtch < switching::cutoff*switching::tolerance) { f[0]=0.; return 0; } */ //Call the counterterm int mode = 0; dofill_.doFill_ = int(iter==last_iter); f[0] = ctint_(costh_CS,m,qt,y,mode,f); //avoid nans if (isnan_ofast(f[0])) { f[0]=0.; if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = 0.; return 0; } //apply switching and jacobian f[0] = f[0]*jac*swtch; if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = f[i]*jac*swtch; if (iter==last_iter) for (int i = 0; i < opts.totpdf; i++) { double wt = weight*f[i]; hists_setpdf_(&i); hists_fill_(phasespace::p3, phasespace::p4, &wt); } end_time = clock(); if (opts.timeprofile) cout << setw (3) << "m" << setw(10) << m << setw(4) << "qt" << setw(10) << qt << setw (3) << "y" << setw(10) << y << setw(4) << "costh" << setw(10) << costh_CS << setw(8) << "result" << setw(10) << f[0] << setw(10) << "tot time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << endl; return 0; } int ctintegrand3d_cubature_v(unsigned ndim, long unsigned npts, const double x[], void *data, unsigned ncomp, double f[]) { tell_to_grid_we_are_alive(); // cout << "parallel " << npts << endl; #pragma omp parallel for num_threads(opts.cubacores) copyin(a_param_,scale_,facscale_,qcdcouple_) for (unsigned i = 0; i < npts; i++) { // evaluate the integrand for npts points double xi[ndim]; double fi[ncomp]; for (unsigned j = 0; j < ndim; j++) xi[j] = x[i*ndim + j]; ctintegrand3d(ndim, xi, ncomp, fi); for (unsigned k = 0; k < ncomp; ++k) f[i*ncomp + k] = fi[k]; } return 0; } int ctintegrand3d_cubature(unsigned ndim, const double x[], void *data, unsigned ncomp, double f[]) { tell_to_grid_we_are_alive(); ctintegrand3d(ndim, x, ncomp, f); return 0; } integrand_t ctintegrand3d(const int &ndim, const double x[], const int &ncomp, double f[]) //Generates the phase space 4 vectors //Calculates the ct integrand as a function of m, qt, y //dOmega integration is factorised in the costh moments //The integration in alpha and beta is performed inside countdy { tell_to_grid_we_are_alive(); clock_t begin_time, end_time; begin_time = clock(); if (opts.fixedorder && phasespace::qtmin > 0) { f[0]=0.; return 0; } if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = 0.; //Jacobian of the change of variables from the unitary hypercube x[3] to the m, y, qt boundaries double jac = 1.; bool status = true; double r2[2] = {x[0], x[1]}; status = phasespace::gen_my(r2, jac, true, !opts.fixedorder); //qtcut = true, qtswitching = true if (!status) { f[0] = 0.; return 0; } double qt; //In the fixed order calculation, integrate from qtcut to infinity if (opts.fixedorder) { phasespace::gen_qt_ctfo(x[2], jac); qt = phasespace::qt; phasespace::set_qt(0.); //In the fixed order calculation evaluate kinematic cuts with qt=0 } else { //Generate the boson transverse momentum between the integration boundaries double qtcut = max(opts.qtcut,opts.xqtcut*phasespace::m); double qtmn = max(qtcut, phasespace::qtmin); //phasespace::calcexpy(); //double cosh2y=pow((phasespace::exppy+phasespace::expmy)*0.5,2); //double kinqtlim = sqrt(max(0.,pow(pow(opts.sroot,2)+phasespace::m2,2)/(4*pow(opts.sroot,2)*cosh2y)-phasespace::m2)); //introduced max to avoid neqative argument of sqrt when y=ymax //double kinqtlim = sqrt(max(0.,pow(pow(opts.sroot,2)+phasespace::m2,2)/(4*pow(opts.sroot,2))-phasespace::m2)); //introduced max to avoid negative argument of sqrt when y=ymax double kinqtlim = ctlimit; //There should not be any kinematic limit on qt, since the counterterm is evaluated with born level kinematic double switchqtlim = switching::qtlimit(phasespace::m); double qtlim = min(kinqtlim, switchqtlim); double qtmx = min(qtlim, phasespace::qtmax); if (qtmn >= qtmx) { f[0] = 0.; return 0; } status = phasespace::gen_qt(x[2], jac, qtlim, true); if (!status) { f[0] = 0.; return 0; } qt = phasespace::qt; } jac = jac *2.*qt; phasespace::set_phiV(0.); double m = phasespace::m; double y = phasespace::y; if (opts.ctcpp) qtint::calc(m,qt,0,1); //generate boson 4-momentum, with m, qt, y and phi=0 omegaintegr::genV4p(); //switching is applied inside countdy //double swtch = switching::swtch(qt, m); //In this point of phase space (m, qt, y) the costh integration is performed by //calculating the 0, 1 and 2 moments of costh //that are the integrals int(dcosth dphi1 dphi2), int(costh dcosth dphi1 dphi2), and int(costh^2 dcosth dphi1 dphi2) convoluted with cuts //Then the epxressions 1, costh and costh^2 in sigmaij are substituted by these costh moments double costh = 0; int mode = 1; dofill_.doFill_ = 1; //No need to check the switching, since the phase space is generated up to the switching qt limit //if (swtch < switching::cutoff*switching::tolerance) //{ // f[0]=0.; // return 0; //} //evaluate the fixed order expansion of the resummed cross section if (opts.ctcpp) ctint::calc(costh,m,qt,y,mode,f); else f[0]=ctint_(costh,m,qt,y,mode,f); //avoid nans if (isnan_ofast(f[0])) { cout << "nan in ctintegrand3d" << endl; f[0]=0.; if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = 0.; return 0; } f[0] = f[0]*jac; //*swtch; switching function is inside ctint_ if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = f[i]*jac; end_time = clock(); if (opts.timeprofile) cout << setw (3) << "m" << setw(10) << m << setw(4) << "qt" << setw(10) << qt << setw(4) << "y" << setw(10) << y << setw(8) << "result" << setw(10) << f[0] << setw(10) << "tot time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << endl; return 0; } int ctintegrand2d_cubature_v(unsigned ndim, long unsigned npts, const double x[], void *data, unsigned ncomp, double f[]) { tell_to_grid_we_are_alive(); // cout << "parallel " << npts << endl; #pragma omp parallel for num_threads(opts.cubacores) copyin(a_param_,scale_,facscale_,qcdcouple_) for (unsigned i = 0; i < npts; i++) { // evaluate the integrand for npts points double xi[ndim]; double fi[ncomp]; for (unsigned j = 0; j < ndim; j++) xi[j] = x[i*ndim + j]; ctintegrand2d(ndim, xi, ncomp, fi); for (unsigned k = 0; k < ncomp; ++k) f[i*ncomp + k] = fi[k]; } return 0; } int ctintegrand2d_cubature(unsigned ndim, const double x[], void *data, unsigned ncomp, double f[]) { tell_to_grid_we_are_alive(); ctintegrand2d(ndim, x, ncomp, f); return 0; } integrand_t ctintegrand2d(const int &ndim, const double x[], const int &ncomp, double f[]) //Calculates the ct integrand as a function of m, y //The integration in qt is factorised in LL1, LL2, LL3 and LL4 large logs //dOmega integration is factorised in the costh moments //The integration in alpha and beta is performed inside countdy { tell_to_grid_we_are_alive(); clock_t begin_time, end_time; begin_time = clock(); if (opts.fixedorder && phasespace::qtmin > 0) { f[0]=0.; return 0; } if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = 0.; //Jacobian of the change of variables from the unitary hypercube x[3] to the m, y, qt boundaries double jac = 1.; bool status = true; double r2[2] = {x[0], x[1]}; status = phasespace::gen_my(r2, jac, true, !opts.fixedorder); //qtcut = true, qtswitching = true if (!status) { f[0] = 0.; return 0; } double qtcut = max(opts.qtcut,opts.xqtcut*phasespace::m); double qtmn, qtmx; //In the fixed order calculation, integrate from qtcut to infinity if (opts.fixedorder) { qtmn = qtcut; qtmx = ctlimit; phasespace::set_qt(0.); //In the fixed order calculation evaluate kinematic cuts with qt=0 } else { //Generate the boson transverse momentum between the integration boundaries qtmn = max(qtcut, phasespace::qtmin); //phasespace::calcexpy(); //double cosh2y=pow((phasespace::exppy+phasespace::expmy)*0.5,2); //double kinqtlim = sqrt(max(0.,pow(pow(opts.sroot,2)+phasespace::m2,2)/(4*pow(opts.sroot,2)*cosh2y)-phasespace::m2)); //introduced max to avoid neqative argument of sqrt when y=ymax //double kinqtlim = sqrt(max(0.,pow(pow(opts.sroot,2)+phasespace::m2,2)/(4*pow(opts.sroot,2))-phasespace::m2)); //introduced max to avoid negative argument of sqrt when y=ymax double kinqtlim = ctlimit; //There should not be any kinematic limit on qt, since the counterterm is evaluated with born level kinematic double switchqtlim = switching::qtlimit(phasespace::m); double qtlim = min(kinqtlim, switchqtlim); qtmx = min(qtlim, phasespace::qtmax); if (qtmn >= qtmx) { f[0] = 0.; return 0; } phasespace::set_qt((qtmn+qtmx)/2.); //Is this actually needed? } phasespace::set_phiV(0.); double m = phasespace::m; double y = phasespace::y; clock_t qtbt, qtet; qtbt = clock(); if (opts.ctcpp) qtint::calc(m,qtmn,qtmx,2); else ctqtint_(m,y,qtmn,qtmx); qtet = clock(); //generate boson 4-momentum, with m, qt, y and phi=0 (not actually needed) omegaintegr::genV4p(); //In this point of phase space (m, qt, y) the costh integration is performed by //calculating the 0, 1 and 2 moments of costh //that are the integrals int(dcosth dphi1 dphi2), int(costh dcosth dphi1 dphi2), and int(costh^2 dcosth dphi1 dphi2) convoluted with cuts //Then the epxressions 1, costh and costh^2 in sigmaij are substituted by these costh moments double costh = 0; int mode = 2; dofill_.doFill_ = 1; //evaluate the fixed order expansion of the resummed cross section double qt = (qtmn+qtmx)/2.; clock_t cbt = clock(); if (opts.ctcpp) ctint::calc(costh,m,qt,y,mode,f); else f[0]=ctint_(costh,m,qt,y,mode,f); clock_t cet = clock(); //avoid nans if (isnan_ofast(f[0])) { cout << "nan in ctintegr 2d " << endl; f[0]=0.; if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = 0.; return 0; } f[0] = f[0]*jac; if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = f[i]*jac; end_time = clock(); if (opts.timeprofile) cout << setw (3) << "m" << setw(10) << m << setw(4) << "y" << setw(10) << y << setw(8) << "result" << setw(10) << f[0] << setw(10) << "tot time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << setw(10) << "qtint" << setw(10) << float( qtet - qtbt ) / CLOCKS_PER_SEC << setw(10) << "ctint" << setw(10) << float( cet - cbt ) / CLOCKS_PER_SEC << endl; return 0; } int ctintegrand1d_cubature_v(unsigned ndim, long unsigned npts, const double x[], void *data, unsigned ncomp, double f[]) { tell_to_grid_we_are_alive(); // cout << "parallel " << npts << endl; #pragma omp parallel for num_threads(opts.cubacores) copyin(a_param_,scale_,facscale_,qcdcouple_) for (unsigned i = 0; i < npts; i++) { // evaluate the integrand for npts points double xi[ndim]; double fi[ncomp]; for (unsigned j = 0; j < ndim; j++) xi[j] = x[i*ndim + j]; ctintegrand1d(ndim, xi, ncomp, fi); for (unsigned k = 0; k < ncomp; ++k) f[i*ncomp + k] = fi[k]; } return 0; } int ctintegrand1d_cubature(unsigned ndim, const double x[], void *data, unsigned ncomp, double f[]) { tell_to_grid_we_are_alive(); ctintegrand1d(ndim, x, ncomp, f); return 0; } integrand_t ctintegrand1d(const int &ndim, const double x[], const int &ncomp, double f[]) //Calculates the ct integrand as a function of m, //The integration in qt is factorised in LL1, LL2, LL3 and LL4 large logs //dOmega integration is factorised in the costh moments //The y integration is achieved by means of a single Mellin inversion { tell_to_grid_we_are_alive(); clock_t begin_time, end_time; begin_time = clock(); if (opts.fixedorder && phasespace::qtmin > 0) { f[0]=0.; return 0; } if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = 0.; //Jacobian of the change of variables from the unitary segment x[0] to the m boundaries double jac = 1.; bool status = true; //This integration currently works only for the full y range, so the mass limit is sqrt(s) double mlim = opts.sroot; double r1 = {x[0]}; status = phasespace::gen_m(r1, jac, mlim, true, true); //qtcut = true, qtswitching = true if (!status) { f[0] = 0.; return 0; } double qtcut = max(opts.qtcut,opts.xqtcut*phasespace::m); double qtmn, qtmx; //In the fixed order calculation, integrate from qtcut to infinity if (opts.fixedorder) { qtmn = qtcut; qtmx = ctlimit; phasespace::set_qt(0.); //In the fixed order calculation evaluate kinematic cuts with qt=0 } else { //Generate the boson transverse momentum between the integration boundaries qtmn = max(qtcut, phasespace::qtmin); //phasespace::calcexpy(); //double cosh2y=pow((phasespace::exppy+phasespace::expmy)*0.5,2); //double kinqtlim = sqrt(max(0.,pow(pow(opts.sroot,2)+phasespace::m2,2)/(4*pow(opts.sroot,2)*cosh2y)-phasespace::m2)); //introduced max to avoid neqative argument of sqrt when y=ymax //double kinqtlim = sqrt(max(0.,pow(pow(opts.sroot,2)+phasespace::m2,2)/(4*pow(opts.sroot,2))-phasespace::m2)); //introduced max to avoid negative argument of sqrt when y=ymax double kinqtlim = ctlimit; //There should not be any kinematic limit on qt, since the counterterm is evaluated with born level kinematic double switchqtlim = switching::qtlimit(phasespace::m); double qtlim = min(kinqtlim, switchqtlim); qtmx = min(qtlim, phasespace::qtmax); if (qtmn >= qtmx) { f[0] = 0.; return 0; } phasespace::set_qt((qtmn+qtmx)/2.); //Is this actually needed? } phasespace::set_phiV(0.); phasespace::set_y(0.); double m = phasespace::m; //double y = phasespace::y; clock_t qtbt, qtet; qtbt = clock(); qtint::calc(m,qtmn,qtmx,2); qtet = clock(); //generate boson 4-momentum, with m, qt, y and phi=0 (not actually needed) omegaintegr::genV4p(); //In this point of phase space (m, qt, y) the costh integration is performed by //calculating the 0, 1 and 2 moments of costh //that are the integrals int(dcosth dphi1 dphi2), int(costh dcosth dphi1 dphi2), and int(costh^2 dcosth dphi1 dphi2) convoluted with cuts //Then the epxressions 1, costh and costh^2 in sigmaij are substituted by these costh moments double costh = 0; int mode = 2; dofill_.doFill_ = 1; //evaluate the fixed order expansion of the resummed cross section double qt = (qtmn+qtmx)/2.; clock_t cbt = clock(); ctmellin::calc(m,f); clock_t cet = clock(); //avoid nans if (isnan_ofast(f[0])) { cout << "nan in ctintegr 2d " << endl; f[0]=0.; if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = 0.; return 0; } // cout << "counterterm " << f[0] << " m " << m << " jac " << jac << endl; f[0] = f[0]*jac; if (opts.PDFerrors) for (int i = 1; i < opts.totpdf; i++) f[i] = f[i]*jac; end_time = clock(); if (opts.timeprofile) cout << setw (3) << "m" << setw(10) << m << setw(8) << "result" << setw(10) << f[0] << setw(10) << "tot time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << setw(10) << "qtint" << setw(10) << float( qtet - qtbt ) / CLOCKS_PER_SEC << setw(10) << "ctint" << setw(10) << float( cet - cbt ) / CLOCKS_PER_SEC << endl; return 0; } diff --git a/src/cubacall.C b/src/cubacall.C index 4f97cc1..cd99a56 100644 --- a/src/cubacall.C +++ b/src/cubacall.C @@ -1,994 +1,1008 @@ #include "cubacall.h" #include "settings.h" #include "resintegr.h" #include "ctintegr.h" #include "finintegr.h" #include "bornintegr.h" #include "cubature.h" #include "smolpack.h" #include "phasespace.h" #include "HistoHandler.h" #include #include //flags for cuba Vegas integration: //flags += 0 or 4; //collect only weights from final iteration (4) or from all iterations (0) //flags = 8; //smoothing of importance sampling (0) or not (8) /***************************************************************/ //resummation void resintegr1d(vector &res, double &err) { //Force qt differential mode when crossing the value of qt where the switching start if (opts.damp && (phasespace::qtmax > phasespace::mmin*opts.dampk)) { resintegr2d(res, err); return; } const int ndim = 1; //dimensions of the integral const int ncomp = 1; //components of the integrand void *userdata = NULL; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 0+opts.cubaverbosity; const int mineval = 65+2*65*opts.niterBORN; const int maxeval = 65+2*65*opts.niterBORN; const int key = 13; int nregions; if (!opts.pcubature) Cuhre(ndim, ncomp, (integrand_t) resintegrand2d, userdata, nvec, epsrel, epsabs, flags, mineval, maxeval, key, statefile, NULL, &nregions, &neval, &fail, integral, error, prob); else { const int eval = 0; const double epsrel = opts.relaccuracy; const double epsabs = opts.absaccuracy; double xmin[1] = {0}; double xmax[1] = {1}; if (opts.cubacores == 0) pcubature(ncomp, resintegrand1d_cubature, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); else pcubature_v(ncomp, resintegrand1d_cubature_v, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); } res.clear(); res.push_back(integral[0]); for (int i = 1; i < opts.totpdf; i++) res.push_back(0); err = error[0]; return; } void resintegr2d(vector &res, double &err) { const int ndim = 2; //dimensions of the integral const int ncomp = 1; //components of the integrand void *userdata = NULL; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 0+opts.cubaverbosity; const int mineval = 65+2*65*opts.niterBORN; const int maxeval = 65+2*65*opts.niterBORN; const int key = 13; int nregions; if (!opts.pcubature) Cuhre(ndim, ncomp, (integrand_t) resintegrand2d, userdata, nvec, epsrel, epsabs, flags, mineval, maxeval, key, statefile, NULL, &nregions, &neval, &fail, integral, error, prob); else { const int eval = 0; const double epsrel = opts.relaccuracy; const double epsabs = opts.absaccuracy; double xmin[2] = {0, 0}; double xmax[2] = {1, 1}; if (opts.cubacores == 0) pcubature(ncomp, resintegrand2d_cubature, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); else pcubature_v(ncomp, resintegrand2d_cubature_v, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); } res.clear(); res.push_back(integral[0]); for (int i = 1; i < opts.totpdf; i++) res.push_back(0); err = error[0]; return; } void resintegr3d(vector &res, double &err) { const int ndim = 3; //dimensions of the integral const int ncomp = 1; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 0+opts.cubaverbosity; const int mineval = 127+2*127*opts.niterBORN; const int maxeval = 127+2*127*opts.niterBORN; const int key = 13; int nregions; Cuhre(ndim, ncomp, (integrand_t) resintegrand3d, userdata, nvec, epsrel, epsabs, flags, mineval, maxeval, key, statefile, NULL, &nregions, &neval, &fail, integral, error, prob); res.clear(); res.push_back(integral[0]); for (int i = 1; i < opts.totpdf; i++) res.push_back(0); err = error[0]; return; } //original integration, can use this to sample phase space and fill histograms void resintegrMC(vector &res, double &err) { const int ndim = 6; //dimensions of the integral const int ncomp = 1; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = (4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const int mineval = opts.vegasncallsBORN; const int maxeval = opts.vegasncallsBORN; const int nstart = max(10, int(opts.vegasncallsBORN/10)); const int nincrease = max(10, int(opts.vegasncallsBORN/10)); const int nbatch = opts.cubanbatch; const int gridno = 0; Vegas(ndim, ncomp, (integrand_t)resintegrandMC, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); res.clear(); res.push_back(integral[0]); for (int i = 1; i < opts.totpdf; i++) res.push_back(0); err = error[0]; return; } /***************************************************************/ /***************************************************************/ // fixed order //Cuba integration of analytical V+j void vjintegr3d(vector &res, double &err) { const int ndim = 3; //dimensions of the integral const int ncomp = 1; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 0+opts.cubaverbosity; const int mineval = 127+2*127*opts.niterVJ; const int maxeval = 127+2*127*opts.niterVJ; const int key = 13; int nregions; if (!opts.pcubature) Cuhre(ndim, ncomp, (integrand_t) vjintegrand, userdata, nvec, epsrel, epsabs, flags, mineval, maxeval, key, statefile, NULL, &nregions, &neval, &fail, integral, error, prob); else { const int eval = 0; const double epsrel = opts.relaccuracy; const double epsabs = opts.absaccuracy; double xmin[3] = {0, 0., 0.}; double xmax[3] = {1, 1., 1.}; if (opts.cubacores == 0) pcubature(ncomp, vjintegrand_cubature, userdata, //hcubature(ncomp, vjintegrand_cubature, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); else pcubature_v(ncomp, vjintegrand_cubature_v, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); /* //smolyak int print_stats = 0; int dim = ndim; int l = 10; integral[0] = int_smolyak (ndim, ndim+l, vjintegrand_smolyak, print_stats ); error[0] = 0.000000001; */ } res.clear(); res.push_back(integral[0]); for (int i = 1; i < opts.totpdf; i++) res.push_back(0); err = error[0]; return; } //Cuba integration of V+j LO void vjlointegr(vector &res, double &err) { const int ndim = 7; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 8+(4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const int mineval = opts.vegasncallsVJLO; const int maxeval = opts.vegasncallsVJLO; const int nstart = max(10, int(opts.vegasncallsVJLO/10)); const int nincrease = max(10, int(opts.vegasncallsVJLO/10)); const int nbatch = opts.cubanbatch; const int gridno = 0; Vegas(ndim, ncomp, (integrand_t)lowintegrand, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; return; } void vjlointegr7d(vector &res, double &err) { const int ndim = 7; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 8+(4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const int mineval = opts.vegasncallsVJLO; const int maxeval = opts.vegasncallsVJLO; const int nstart = max(10, int(opts.vegasncallsVJLO/10)); const int nincrease = max(10, int(opts.vegasncallsVJLO/10)); const int nbatch = opts.cubanbatch; const int gridno = 0; Vegas(ndim, ncomp, (integrand_t)vjlointegrandMC, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; return; } void vjlointegr5d(vector &res, double &err) { const int ndim = 4;//5; //dimensions of the integral const int ncomp = (opts.helicity >= 0 ? 2 : 1); //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 0+opts.cubaverbosity; const int mineval = 153+2*153*opts.niterVJ; const int maxeval = 153+2*153*opts.niterVJ; const int key = 13; int nregions; if (!opts.pcubature) Cuhre(ndim, ncomp, (integrand_t) vjlointegrand, userdata, nvec, epsrel, epsabs, flags, mineval, maxeval, key, statefile, NULL, &nregions, &neval, &fail, integral, error, prob); else { const int eval = 0; const double epsrel = opts.relaccuracy; const double epsabs = opts.absaccuracy; double tiny = 0.;//1e-6; /* double xmin[5] = {0., 0., tiny, 0., 0.}; double xmax[5] = {1., 1., 1.-tiny, 1., 1.}; //if (opts.cubacores == 0) //pcubature(ncomp, vjlointegrand_cubature, userdata, //--> pcubature has an issue when phi is symmetric, it is resonant for nested quadrature rules, and pcubature misses the substructure of the phi distribution hcubature(ncomp, vjlointegrand_cubature, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); */ // /* //4d integration (phi_lep integrated inside) works better in full phase space, and to calculate moments double xmin[4] = {0., 0., tiny, 0.}; double xmax[4] = {1., 1., 1.-tiny, 1.}; if (opts.cubacores == 0) //pcubature(ncomp, vjlointegrand_cubature, userdata, //--> pcubature has an issue when phi is symmetric, it is resonant for nested quadrature rules, and pcubature misses the substructure of the phi distribution hcubature(ncomp, vjlointegrand_cubature, userdata, 4, xmin, xmax, eval, epsabs, epsrel, ERROR_LINF, integral, error); else //pcubature_v(ncomp, vjlointegrand_cubature_v, userdata, hcubature_v(ncomp, vjlointegrand_cubature_v, userdata, 4, xmin, xmax, eval, epsabs, epsrel, ERROR_LINF, integral, error); // */ /* //smolyak int print_stats = 0; int dim = 4; int l = 20; integral[0] = int_smolyak (ndim, ndim+l, vjlointegrand_smolyak, print_stats ); error[0] = 0.000001; */ } res.clear(); if (opts.helicity >= 0) res.push_back(integral[0] != 0? integral[1]/integral[0] : 0); else res.push_back(integral[0]); for (int i = 1; i < opts.totpdf; i++) res.push_back(0); if (opts.helicity >= 0) err = integral[0] != 0? error[0]/integral[0]*integral[1]/integral[0] : 0; // error[1]/integral[1]*integral[1]/integral[0] else err = error[0]; return; } //Cuba integration of the V+J NLO real part void vjrealintegr(vector &res, double &err) { const int ndim = 10; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata; const long long int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; long long int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 8+(4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const long long int mineval = opts.vegasncallsVJREAL; const long long int maxeval = opts.vegasncallsVJREAL; const long long int nstart = max(10, int(opts.vegasncallsVJREAL/10)); const long long int nincrease = max(10, int(opts.vegasncallsVJREAL/10)); const long long int nbatch = opts.cubanbatch; const int gridno = 0; llVegas(ndim, ncomp, (integrand_t)realintegrand, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); /* //smolyak int print_stats = 0; int dim = 10; int l = 12; integral[0] = int_smolyak (ndim, ndim+l, realintegrand_smolyak, print_stats ); error[0] = 0.000001; */ res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; return; } //Cuba integration of the V+J NLO virtual part void vjvirtintegr(vector &res, double &err) { const int ndim = 8; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 8+(4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const int mineval = opts.vegasncallsVJVIRT; const int maxeval = opts.vegasncallsVJVIRT; const int nstart = max(10, int(opts.vegasncallsVJVIRT/10)); const int nincrease = max(10, int(opts.vegasncallsVJVIRT/10)); const int nbatch = opts.cubanbatch; const int gridno = 0; Vegas(ndim, ncomp, (integrand_t)virtintegrand, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; return; } //Cuba integration of double virtual born configuration void bornintegrMC6d(vector &res, double &err) { const int ndim = 6; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 8+(4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const int mineval = opts.vegasncallsBORN; const int maxeval = opts.vegasncallsBORN; const int nstart = max(10, int(opts.vegasncallsBORN/10)); const int nincrease = max(10, int(opts.vegasncallsBORN/10)); const int nbatch = opts.cubanbatch; const int gridno = 0; Vegas(ndim, ncomp, (integrand_t)doublevirtintegrand, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; return; } //Cuba integration of LO void bornintegrMC4d(vector &res, double &err) { const int ndim = 4; //dimensions of the integral const int ncomp = 1; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 8+(4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const int mineval = opts.vegasncallsBORN; const int maxeval = opts.vegasncallsBORN; const int nstart = max(10, int(opts.vegasncallsBORN/10)); const int nincrease = max(10, int(opts.vegasncallsBORN/10)); const int nbatch = opts.cubanbatch; const int gridno = 0; Vegas(ndim, ncomp, (integrand_t)lointegrandMC, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); res.clear(); res.push_back(integral[0]); for (int i = 1; i < opts.totpdf; i++) res.push_back(0); err = error[0]; return; } //Cuba integration of LO void bornintegr2d(vector &res, double &err) { const int ndim = 2; //dimensions of the integral const int ncomp = (opts.helicity >= 0 ? 2 : 1); //components of the integrand void *userdata = NULL; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 0+opts.cubaverbosity; const int mineval = 65+2*65*opts.niterBORN; const int maxeval = 65+2*65*opts.niterBORN; const int key = 13; int nregions; if (!opts.pcubature) Cuhre(ndim, ncomp, (integrand_t) lointegrand2d, userdata, nvec, epsrel, epsabs, flags, mineval, maxeval, key, statefile, NULL, &nregions, &neval, &fail, integral, error, prob); else { const int eval = 0; const double epsrel = opts.relaccuracy; const double epsabs = opts.absaccuracy; double xmin[2] = {0, 0}; double xmax[2] = {1, 1}; if (opts.cubacores == 0) pcubature(ncomp, lointegrand2d_cubature, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); else pcubature_v(ncomp, lointegrand2d_cubature_v, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); /* //smolyak int print_stats = 0; int dim = 2; int l = 10; integral[0] = int_smolyak (ndim, ndim+l, lointegrand2d_smolyak, print_stats ); error[0] = 0.000001; */ } res.clear(); /* res.push_back(integral[0]); for (int i = 1; i < opts.totpdf; i++) res.push_back(0); err = error[0]; */ if (opts.helicity >= 0) res.push_back(integral[0] != 0? integral[1]/integral[0] : 0); else res.push_back(integral[0]); for (int i = 1; i < opts.totpdf; i++) res.push_back(0); if (opts.helicity >= 0) err = integral[0] != 0? error[0]/integral[0]*integral[1]/integral[0] : 0; // error[1]/integral[1]*integral[1]/integral[0] else err = error[0]; return; return; } //Cuba integration of V + 2 jets void v2jintegr(vector &res, double &err) { const int ndim = 10; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 8+(4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const int mineval = opts.vegasncallsVJREAL; const int maxeval = opts.vegasncallsVJREAL; const int nstart = max(10, int(opts.vegasncallsVJREAL/10)); const int nincrease = max(10, int(opts.vegasncallsVJREAL/10)); const int nbatch = opts.cubanbatch; const int gridno = 0; Vegas(ndim, ncomp, (integrand_t)v2jintegrand, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; return; } /***************************************************************/ /***************************************************************/ // Counter term //Cuba integration of the counterterm void ctintegr(vector &res, double &err) { const int ndim = 8; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 8+(4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const int mineval = opts.vegasncallsCT; const int maxeval = opts.vegasncallsCT; const int nstart = max(10, int(opts.vegasncallsCT/10)); const int nincrease = max(10, int(opts.vegasncallsCT/10)); const int nbatch = opts.cubanbatch; const int gridno = 0; Vegas(ndim, ncomp, (integrand_t)ctintegrand, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; return; } //Cuba integration of the counterterm void ctintegrMC(vector &res, double &err) { const int ndim = 6; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 8+(4*!opts.vegascollect)+opts.cubaverbosity; const int seed = opts.rseed; const int mineval = opts.vegasncallsCT; const int maxeval = opts.vegasncallsCT; const int nstart = max(10, int(opts.vegasncallsCT/10)); const int nincrease = max(10, int(opts.vegasncallsCT/10)); const int nbatch = opts.cubanbatch; const int gridno = 0; Vegas(ndim, ncomp, (integrand_t)ctintegrandMC, userdata, nvec, epsrel, epsabs, flags, seed, mineval, maxeval, nstart, nincrease, nbatch, gridno, statefile, spin, &neval, &fail, integral, error, prob); res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; return; } void ctintegr3d(vector &res, double &err) { const int ndim = 3; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 0+opts.cubaverbosity; const int mineval = 127+2*127*opts.niterCT; const int maxeval = 127+2*127*opts.niterCT; const int key = 13; int nregions; if (!opts.pcubature) Cuhre(ndim, ncomp, (integrand_t) ctintegrand3d, userdata, nvec, epsrel, epsabs, flags, mineval, maxeval, key, statefile, NULL, &nregions, &neval, &fail, integral, error, prob); else { const int eval = 0; const double epsrel = opts.relaccuracy; const double epsabs = opts.absaccuracy; double xmin[3] = {0, 0., 0.}; double xmax[3] = {1, 1., 1.}; if (opts.cubacores == 0) pcubature(ncomp, ctintegrand3d_cubature, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); else pcubature_v(ncomp, ctintegrand3d_cubature_v, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); } res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; //hists.FillQuadrature(res[0],err); return; } void ctintegr2d(vector &res, double &err) { const int ndim = 2; //dimensions of the integral const int ncomp = opts.totpdf; //components of the integrand void *userdata = NULL; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 0+opts.cubaverbosity; const int mineval = 65+2*65*opts.niterCT; const int maxeval = 65+2*65*opts.niterCT; const int key = 13; int nregions; if (!opts.pcubature) Cuhre(ndim, ncomp, (integrand_t) ctintegrand2d, userdata, nvec, epsrel, epsabs, flags, mineval, maxeval, key, statefile, NULL, &nregions, &neval, &fail, integral, error, prob); else { const int eval = 0; const double epsrel = opts.relaccuracy; const double epsabs = opts.absaccuracy; double xmin[2] = {0, 0.}; double xmax[2] = {1, 1.}; if (opts.cubacores == 0) pcubature(ncomp, ctintegrand2d_cubature, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); else pcubature_v(ncomp, ctintegrand2d_cubature_v, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); } res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; //hists.FillQuadrature(res[0],err); return; } void ctintegr1d(vector &res, double &err) { const int ndim = 1; //dimensions of the integral - const int ncomp = opts.totpdf; //components of the integrand + const int ncomp = 1; //components of the integrand void *userdata = NULL; const int nvec = 1; const double epsrel = 0.; const double epsabs = 0.; const char *statefile = ""; void *spin=NULL; int neval; int fail; double integral[ncomp]; double error[ncomp]; double prob[ncomp]; const int flags = 0+opts.cubaverbosity; const int mineval = 65+2*65*opts.niterCT; const int maxeval = 65+2*65*opts.niterCT; const int key = 13; int nregions; if (!opts.pcubature) Cuhre(ndim, ncomp, (integrand_t) ctintegrand1d, userdata, nvec, epsrel, epsabs, flags, mineval, maxeval, key, statefile, NULL, &nregions, &neval, &fail, integral, error, prob); else { const int eval = 0; const double epsrel = opts.relaccuracy; const double epsabs = opts.absaccuracy; double xmin[1] = {0.}; double xmax[1] = {1.}; if (opts.cubacores == 0) pcubature(ncomp, ctintegrand1d_cubature, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); else pcubature_v(ncomp, ctintegrand1d_cubature_v, userdata, ndim, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); } res.clear(); for (int i = 0; i < opts.totpdf; i++) res.push_back(integral[i]); err = error[0]; //hists.FillQuadrature(res[0],err); return; } /***************************************************************/ +void tell_to_grid_we_are_alive(){ + if(opts.gridverbose && ICALL % 100000==0) + { + if (opts.redirect) fclose (stdout); + printf (" Hi Grid, we are sitll alive! Look, our event is %d\n",ICALL); + if (opts.redirect) + { + string logfile = opts.output_filename + ".log"; + freopen(logfile.c_str(),"w",stdout); + } + } + ICALL++; +} -void initfun(void * input, const int &core){ +void cuba::initfun(void * input, const int &core){ if(core != PARENT_PROC) HistoHandler::Reset(); } -void exitfun(void * input, const int &core){ +void cuba::exitfun(void * input, const int &core){ HistoHandler::Save(core); } -void tell_to_grid_we_are_alive(){ - if(opts.gridverbose && ICALL % 100000==0) - printf (" Hi Grid, we are sitll alive! Look, our event is %d\n",ICALL); - ICALL++; +void cuba::init() +{ + cubacores(opts.cubacores,1000000); //< set number of cores + cubainit((void (*)()) initfun,NULL); //< merge at the end of the run + cubaexit((void (*)()) exitfun,NULL); //< merge at the end of the run } diff --git a/src/cubacall.h b/src/cubacall.h index 7bb7ac6..0fde41c 100644 --- a/src/cubacall.h +++ b/src/cubacall.h @@ -1,42 +1,50 @@ #ifndef cubacall_h #define cubacall_h +//--> Make this a namelist, with a different name (f.i. integration) +//--> Wrap into general methods which can handle different integration routines (Cuba, cubature, Smolyak, Sparse grids, etc...) + const int last_iter=4; static int ICALL=0; // number of integrand calls void tell_to_grid_we_are_alive(); #include using namespace std; //resummation void resintegr1d(vector &res, double &err); //missing Ai void resintegr2d(vector &res, double &err); //missing Ai void resintegr3d(vector &res, double &err); //(missing Ai) void resintegrMC(vector &res, double &err); //missing PDF variations //fixed order born configuration void bornintegr2d(vector &res, double &err); //Ai as dimensions void bornintegrMC4d(vector &res, double &err); //missing PDF variations void bornintegrMC6d(vector &res, double &err); //fixed order V+j void vjintegr3d(vector &res, double &err); //missing PDF variations void vjlointegr5d(vector &res, double &err); //Ai as dimensions void vjlointegr7d(vector &res, double &err); //missing PDF variations void vjlointegr(vector &res, double &err); void vjrealintegr(vector &res, double &err); void vjvirtintegr(vector &res, double &err); void v2jintegr(vector &res, double &err); //counterterm void ctintegr(vector &res, double &err); void ctintegrMC(vector &res, double &err); void ctintegr3d(vector &res, double &err); void ctintegr2d(vector &res, double &err); //PDF variations, swicth to Ai void ctintegr1d(vector &res, double &err); -void initfun(void * input, const int &core); -void exitfun(void * input, const int &core); +//Cuba initialisation +namespace cuba +{ + void init(); + void initfun(void * input, const int &core); + void exitfun(void * input, const int &core); +} #endif diff --git a/src/dyturbo.C b/src/dyturbo.C index b0278ba..807c066 100644 --- a/src/dyturbo.C +++ b/src/dyturbo.C @@ -1,383 +1,434 @@ #ifndef dyturbo_C #define dyturbo_C /** * @file dyturbo.C * Steering class for Drell-Yan calculation. * * @brief A brief description * * @author Jakub Cuth * @date 2016-09-17 */ #include "dyturbo.h" #include "cubacall.h" #include "clock_real.h" #include "settings.h" #include "interface.h" #include "ctintegr.h" #include "phasespace.h" #include "rapint.h" #include "HistoHandler.h" using DYTurbo::PrintTable::Col3; using DYTurbo::PrintTable::Col4; bool DYTurbo::HasOnlyVegas = false; bool DYTurbo::isDryRun = false; -namespace DYTurbo { - - // definition of data member - Term subtotal; - TermList ActiveTerms; - BoundariesList ActiveBoundaries; - BoundIterator last_bounds; - - // Term - - void Term::last_reset() { - last_int.assign(opts.totpdf,0.); - last_err2=0; - last_time = clock_real(); - } - - void Term::RunIntegration(){ - double err; - last_reset(); - /// @todo specialized (need to reincorporate) - if ( integrate == resintegr2d ){ - if (opts.resumcpp) rapint::cache(phasespace::ymin, phasespace::ymax); - else cacheyrapint_(phasespace::ymin, phasespace::ymax); - } - // run - if (isDryRun){ - // this is for testing interface - last_int[0] = 1; err = 1; - } else { - integrate(last_int,err); - } - // - last_time = clock_real()-last_time; - last_err2 += err*err; - // save results to histograms - if (!isVegas){ - for (size_t ivar = 0; ivar < last_int.size(); ++ivar) { - HistoHandler::SetVariation(ivar); - HistoHandler::FillResult(last_int[ivar],sqrt(last_err2)); - } - } - // cumulate - total_time+=last_time; - total_int+=last_int[0]; - total_err2+=last_err2; - // cumulate integral to subtotal - subtotal.last_int[0] += last_int[0]; - subtotal.total_int += last_int[0]; - // cumulate error to subtotal - subtotal.last_err2 += last_err2; - subtotal.total_err2 += last_err2; - } - - void Term::Print(){ - printf("%24s:%s",name.c_str(), description.c_str()); - } - - // Term iterator - - TermIterator::TermIterator() : icurrent(0) { } - - bool TermIterator::IsEnd(){ - return icurrent==ActiveTerms.size(); - } - - TermIterator & TermIterator::operator++(){ - icurrent++; - return (*this); - } - - Term & TermIterator::operator*(){ - return ActiveTerms[icurrent]; - } - - // Boundary iterator - - BoundIterator::BoundIterator(){ - // set first boundary - isFirst=true; - current.clear(); - if (!ActiveBoundaries.empty()) - for (size_t i = 0; i < N_boundaries; ++i) { - current.push_back(ActiveBoundaries[i].begin()); - } +namespace DYTurbo +{ + // definition of data member + Term subtotal; + TermList ActiveTerms; + BoundariesList ActiveBoundaries; + BoundIterator last_bounds; + + //Term + + void Term::last_reset() + { + last_int.assign(opts.totpdf,0.); + last_err2=0; + last_time = clock_real(); + } + + void Term::RunIntegration() + { + double err; + last_reset(); + /// @todo specialized (need to reincorporate) + if ( integrate == resintegr2d ){ + if (opts.resumcpp) rapint::cache(phasespace::ymin, phasespace::ymax); + else cacheyrapint_(phasespace::ymin, phasespace::ymax); } - - bool BoundIterator::IsEnd(){ - if (isFirst) return false; - for (size_t i = 0; i < N_boundaries; ++i) - if (current[i] != ActiveBoundaries[i].begin() ) - return false; - return true; + // run + if (isDryRun) // this is for testing interface + { + last_int[0] = 1; err = 1; + } + else + integrate(last_int,err); + // + if (opts.ptbinwidth) {last_int[0] /= (phasespace::qtmax-phasespace::qtmin); err /= (phasespace::qtmax-phasespace::qtmin);} + if (opts.ybinwidth) {last_int[0] /= (phasespace::ymax-phasespace::ymin); err /= (phasespace::ymax-phasespace::ymin);} + if (opts.mbinwidth) {last_int[0] /= (phasespace::mmax-phasespace::mmin); err /= (phasespace::mmax-phasespace::mmin);} + last_time = clock_real()-last_time; + last_err2 += err*err; + // save results to histograms + if (!isVegas) + { + if (opts.makehistos) + for (size_t ivar = 0; ivar < last_int.size(); ++ivar) + { + HistoHandler::SetVariation(ivar); + HistoHandler::FillResult(last_int[ivar],sqrt(last_err2)); + } + } + // cumulate + total_time+=last_time; + total_int+=last_int[0]; + total_err2+=last_err2; + // cumulate integral to subtotal + subtotal.last_int[0] += last_int[0]; + subtotal.total_int += last_int[0]; + // cumulate error to subtotal + subtotal.last_err2 += last_err2; + subtotal.total_err2 += last_err2; + + //// cumulate integral to bintotal + //bintotal.last_int[0] += bin_int[0]; + //bintotal.total_int += last_int[0]; + // cumulate error to subtotal + //bintotal.last_err2 += last_err2; + //bintotal.total_err2 += last_err2; + } + + void Term::Print() + { + printf("%24s:%s",name.c_str(), description.c_str()); + } + + // Term iterator + TermIterator::TermIterator() : icurrent(0) { } + + bool TermIterator::IsEnd() + { + return icurrent==ActiveTerms.size(); + } + + TermIterator & TermIterator::operator++() + { + icurrent++; + return (*this); + } + + Term & TermIterator::operator*() + { + return ActiveTerms[icurrent]; + } + + // Boundary iterator + BoundIterator::BoundIterator() + { + // set first boundary + isFirst=true; + current.clear(); + if (!ActiveBoundaries.empty()) + for (size_t i = 0; i < N_boundaries; ++i) + current.push_back(ActiveBoundaries[i].begin()); + + } + + bool BoundIterator::IsEnd() + { + if (isFirst) return false; + for (size_t i = 0; i < N_boundaries; ++i) + if (current[i] != ActiveBoundaries[i].begin() ) + return false; + return true; + } + + BoundIterator & BoundIterator::operator++() + { + for (int i = N_boundaries-1; i >= 0; --i) { // start from last + current[i]++; // increase + // check if it's equal to previous to last (need two numbers as boundaries) + if(current[i]!=ActiveBoundaries[i].end()-1) break; // go to return + else current[i]=ActiveBoundaries[i].begin(); // is previous to last } - - BoundIterator & BoundIterator::operator++(){ - for (int i = N_boundaries-1; i >= 0; --i) { // start from last - current[i]++; // increase - // check if it's equal to previous to last (need two numbers as boundaries) - if(current[i]!=ActiveBoundaries[i].end()-1) break; // go to return - else current[i]=ActiveBoundaries[i].begin(); // is previous to last - } - /** - * @attention After looping through all of boundary bins it points back - * to beginning. Therefore it is necessary to set `isFirst=false` - */ - if (isFirst) isFirst=false; - return (*this); - } - - void BoundIterator::Print(){ - printf ("Boundaries "); - printf ( "| M : %f -- %f " , *current [ b_M ] , * ( current [ b_M ] +1 ) ) ; - printf ( "| Qt : %f -- %f " , *current [ b_QT ] , * ( current [ b_QT ] +1 ) ) ; - printf ( "| Y : %f -- %f " , *current [ b_Y ] , * ( current [ b_Y ] +1 ) ) ; - printf ( "| CsTh : %f -- %f " , *current [ b_CsTh ] , * ( current [ b_CsTh ] +1 ) ) ; - printf ( "\n"); - } - - - - //! Internal flag only for test purposes - bool TestAllTerms=false; - /** - * @brief Add term to active terms if is requested. - * - * Also it is checked if we are only using Vegas for integration. TYhi - * - * @param isActive If this false then skip all stuff. - * @param fun The pointer to integration function, which should be called for calculation. - * @param name Set the name of term - * @param is_vegas For checking if we need Integration mode. - * - * @return It returns newly added term so we can define description by using stream operator. + * @attention After looping through all of boundary bins it points back + * to beginning. Therefore it is necessary to set `isFirst=false` */ - Term & AddTermIfActive(const bool &isActive, void (* fun)(VecDbl &val,double &err), const String &name, const bool &is_vegas ){ - subtotal.description = ""; - if (!isActive && !TestAllTerms) return subtotal; - ActiveTerms.push_back(Term()); - ActiveTerms.back().name = name; - ActiveTerms.back().description = ""; - ActiveTerms.back().integrate = fun; - ActiveTerms.back().isVegas = is_vegas; - HasOnlyVegas&=is_vegas; - return ActiveTerms.back(); - } + if (isFirst) isFirst=false; + return (*this); + } + + void BoundIterator::Print(){ + printf ("Boundaries "); + printf ( "| M : %f -- %f " , *current [ b_M ] , * ( current [ b_M ] +1 ) ) ; + printf ( "| Qt : %f -- %f " , *current [ b_QT ] , * ( current [ b_QT ] +1 ) ) ; + printf ( "| Y : %f -- %f " , *current [ b_Y ] , * ( current [ b_Y ] +1 ) ) ; + printf ( "| CsTh : %f -- %f " , *current [ b_CsTh ] , * ( current [ b_CsTh ] +1 ) ) ; + printf ( "\n"); + } + + //! Internal flag only for test purposes + bool TestAllTerms=false; + + /** + * @brief Add term to active terms if is requested. + * + * Also it is checked if we are only using Vegas for integration. TYhi + * + * @param isActive If this false then skip all stuff. + * @param fun The pointer to integration function, which should be called for calculation. + * @param name Set the name of term + * @param is_vegas For checking if we need Integration mode. + * + * @return It returns newly added term so we can define description by using stream operator. + */ + Term & AddTermIfActive(const bool &isActive, void (* fun)(VecDbl &val,double &err), const String &name, const bool &is_vegas ){ + subtotal.description = ""; + if (!isActive && !TestAllTerms) return subtotal; + ActiveTerms.push_back(Term()); + ActiveTerms.back().name = name; + ActiveTerms.back().description = ""; + ActiveTerms.back().integrate = fun; + ActiveTerms.back().isVegas = is_vegas; + HasOnlyVegas&=is_vegas; + return ActiveTerms.back(); + } template Term & Term::operator<<(const Streamable &data){ SStream strm; strm << data; description += strm.str(); return (*this); } void AddTerms(){ ActiveTerms.clear(); HasOnlyVegas=true; const bool isVegas=true; const bool isNotVegas=false; int w0=25; int w1=30; int w2=12; int w3=12; string name; // finite born bool fixed_born = opts.doBORN && opts.fixedorder; if (fixed_born || TestAllTerms) { name="Fixed born"; AddTermIfActive ( opts.bornint2d , bornintegr2d , name, isNotVegas ) << Col3( "cuhre (dm, dpt)" , "iter =" , opts.niterBORN ); AddTermIfActive ( opts.bornintvegas4d , bornintegrMC4d , name, isVegas ) << Col3( "vegas 4D" , "ncalls =" , opts.vegasncallsBORN ); AddTermIfActive ( opts.bornintvegas6d , bornintegrMC6d , name, isVegas ) << Col3( "vegas 6D" , "ncalls =" , opts.vegasncallsBORN ); } // resummation bool resum_born = opts.doBORN && !opts.fixedorder; if (resum_born || TestAllTerms) { name="Resummation"; AddTermIfActive ( opts.resint1d , resintegr1d , name , isNotVegas ) << Col3 ( "cuhre (dpt)" , "iter =" , opts.niterBORN ) << Col4 ( "","gauss (dy)" , "nodes =" , opts.yrule ) << Col4 ( "","" , "intervals =" , opts.yintervals ) << Col3 ( "","analytical (dpt)","" ); AddTermIfActive ( opts.resint2d , resintegr2d , name , isNotVegas ) << Col3 ( "cuhre (dm, dpt)" , "iter =" , opts.niterBORN ) << Col4 ( "","gauss (dy)" , "nodes =" , opts.yrule ) << Col4 ( "","" , "intervals =" , opts.yintervals ); AddTermIfActive ( opts.resint3d , resintegr3d , name , isNotVegas ) << Col3 ( "cuhre (dm, dpt, dy)" , "iter =" , opts.niterBORN ); AddTermIfActive ( opts.resintvegas , resintegrMC , name , isVegas ) << Col3 ( "vegas" , "ncalls =" , opts.vegasncallsBORN ); } // CT if (opts.doCT || TestAllTerms) { name="Counter term"; AddTermIfActive ( opts.ctint1d , ctintegr1d , name , isNotVegas ) << Col3 ( "cuhre (dm)" , "iter =" , opts.niterCT ) << Col4 ( "","gauss (dpt)" , "nodes =" , opts.qtrule ) << Col4 ( "","" , "intervals =" , opts.qtintervals ); AddTermIfActive ( opts.ctint2d , ctintegr2d , name , isNotVegas ) << Col3 ( "cuhre (dm, dy)" , "iter =" , opts.niterCT ) << Col4 ( "","gauss (dpt)" , "nodes =" , 20 ) << Col4 ( "","" , "intervals =" , 5 ); AddTermIfActive ( opts.ctint3d , ctintegr3d , name , isNotVegas ) << Col3 ( "cuhre (dm, dpt, dy)" , "iter =" , opts.niterCT ); AddTermIfActive ( opts.ctintvegas6d , ctintegrMC , name , isVegas ) << Col3 ( "vegas 6D" , "ncalls =" , opts.vegasncallsCT ); AddTermIfActive ( opts.ctintvegas8d , ctintegr , name , isVegas ) << Col3 ( "vegas 8D" , "ncalls =" , opts.vegasncallsCT ); } // VJ finite bool vj_finite = opts.doVJ; name="V+J"; if (vj_finite || TestAllTerms){ AddTermIfActive ( opts.vjint3d , vjintegr3d , name , isNotVegas ) << Col3 ( "cuhre (dm, dpt, dy)" , "iter =" , opts.niterVJ ); // VJ LO if (opts.order == 1) { AddTermIfActive ( opts.vjint5d && opts.order == 1 , vjlointegr5d , name , isNotVegas ) << Col3 ( "cuhre 5D???" , "iter =" , opts.niterVJ ); AddTermIfActive ( opts.vjintvegas7d && opts.order == 1 , vjlointegr7d , name , isVegas ) << Col3 ( "vegas 7D" , "ncalls =" , opts.vegasncallsVJLO ); //phase space improved MCFM integration //AddTermIfActive ( opts.vjintvegas7d && opts.order == 1 , vjlointegr , name , isVegas ) << Col3 ( "vegas 7D" , "ncalls =" , opts.vegasncallsVJLO ); //original MCFM integration } // VJ NLO if (!opts.vjint3d && opts.order == 2) { AddTermIfActive ( opts.doVJREAL , vjrealintegr , "V+J Real" , isVegas) << Col3 ( "vegas" , "ncalls =" , opts.vegasncallsVJREAL ); AddTermIfActive ( opts.doVJVIRT , vjvirtintegr , "V+J Virtual" , isVegas) << Col3 ( "vegas" , "ncalls =" , opts.vegasncallsVJVIRT ); } } } /** * @brief Check for Integration mode and add boundary. * * If we have only Vegas calculations we can run with simple boundaries. * This means we will only pick up one bin with lowest and hightest value * as boundaries. * * @param ib Index of variable (\ref BoundaryIndex can be used as input) * @param name Name of boundary. Will be used for printing. * @param bins All boundaries requested from user. * @return Description of return. */ void AddBoundary(size_t ib, string name, VecDbl &bins ){ ActiveBoundaries[ib].name = name; ActiveBoundaries[ib].data.clear(); if (HasOnlyVegas && !opts.force_binsampling){ // simple boundary mode ActiveBoundaries[ib].data.push_back(bins.front()); ActiveBoundaries[ib].data.push_back(bins.back()); } else { // integration mode ActiveBoundaries[ib].data = bins; } } /** * @brief Adding all boundaries * * This have to be done after adding all terms (becaus of check for Vegas * only). * * If adding new boundary definition please also add new enum item into \ref BoundaryIndex. * * @param _inArg Description of param * @return Description of return. */ - void AddBoundaries(){ - ActiveBoundaries.resize(N_boundaries); - VecDbl costh{opts.costhmin , opts.costhmax}; - AddBoundary ( b_M , "q2" , bins.mbins ) ; - AddBoundary ( b_Y , "y" , bins.ybins ) ; - AddBoundary ( b_QT , "qT" , bins.qtbins ) ; - AddBoundary ( b_CsTh , "costh" , costh ); + void AddBoundaries() + { + ActiveBoundaries.resize(N_boundaries); + VecDbl costh{opts.costhmin , opts.costhmax}; + AddBoundary ( b_M , "q2" , bins.mbins ) ; + AddBoundary ( b_Y , "y" , bins.ybins ) ; + AddBoundary ( b_QT , "qT" , bins.qtbins ) ; + AddBoundary ( b_CsTh , "costh" , costh ); } /** * @brief First run of resummation and counter term. * * If using the DYRES approximation for PDFs, make sure that the PDF fit * is initialised in the same way Need to throw a random point according * to a breit wigner, which is used to determine xtauf in the PDF fit * */ void WarmUpResummation(){ double costh, m, qt, y; int mode = 0; if (opts.doBORN || opts.doCT){ if (opts_.approxpdf_ == 1) { srand(opts.rseed); double wsqmin = pow(phasespace::mmin ,2); double wsqmax = pow(phasespace::mmax ,2); double x1=((double)rand()/(double)RAND_MAX); double m2,wt; breitw_(x1,wsqmin,wsqmax,opts.rmass,opts.rwidth,m2,wt); printf( "Initialise PDF fit with mass = %f xtauf = %f \n", sqrt(m2), m2/opts.sroot); costh = 0.; m = sqrt(m2); qt = 1; y = 0; for (int ipdf=0; ipdf &val, vector &err) + { + //Set up integration terms and bins boundaries + DYTurbo::WarmUp(); + + //Loop on phase space bins + for ( DYTurbo::BoundIterator bounds; !bounds.IsEnd(); ++bounds) + { + DYTurbo::SetBounds(bounds); + + //Loop on active terms + for (DYTurbo::TermIterator term; !term.IsEnd(); ++term) + { + (*term).RunIntegration(); + } + + val.push_back(subtotal.last_int[0]); + err.push_back(sqrt(subtotal.last_err2)); + //cout << "dyturbo " << val.size() << " " << subtotal.last_int[0] << " " << sqrt(subtotal.last_err2) << endl; + subtotal.last_reset(); + } + DYTurbo::Terminate(); + } }; #endif /* ifndef dyturbo_C */ diff --git a/src/dyturbo.h b/src/dyturbo.h index f98dc1e..2620c8c 100644 --- a/src/dyturbo.h +++ b/src/dyturbo.h @@ -1,319 +1,328 @@ #ifndef dyturbo_H #define dyturbo_H /** * @file dyturbo.h * Steering class for Drell-Yan calculation. * * @brief A brief description * * @author Jakub Cuth * @date 2016-09-17 */ #include using std::setw; using std::setprecision; #include "handy_typdefs.h" /** * @brief Interface to properly control calculation. * */ -namespace DYTurbo { +namespace DYTurbo +{ /** * @brief Flag for if we need Integration mode. * * If we have only Vegas integration we don't need to run per each bin and * boundaries can be simplified. Only one bin from lowest to highest * value. */ - extern bool HasOnlyVegas; - - //! Debug flag for testing code. - extern bool isDryRun; - - - //forward - struct Term; - struct Boundaries; - struct BoundIterator; - - /** @defgroup MainFunctions Main DYTurbo functions. - * @{ - */ + extern bool HasOnlyVegas; + + //! Debug flag for testing code. + extern bool isDryRun; + + + //forward + struct Term; + struct Boundaries; + struct BoundIterator; + + /** @defgroup MainFunctions Main DYTurbo functions. + * @{ + */ + + /** + * @brief Initialization of program. + * + * It parse command line and input file and set interfaced values. It's + * also calling initialization of submodules. + */ + void Init(int argc, char * argv[]); + + //Initialise constants + void init_const(); + /** + * @brief Initialization of submodules. + */ + void init_params(); + + //release memory allocated by init_params() + void release(); + + /** + * @brief Warming up integration. + * + * Some of terms needed to be pre-run before actual integration. This done + * inside this function. It also prints out current integration settings. + */ + void WarmUp(); + + /** + * @brief Set integration bounds. + * + * The values from Boundaries are read and provided to \ref phasespace. + * + * @attention This needs to be called before calling the \ref RunIntegration. + */ + void SetBounds(BoundIterator); + + /** + * @brief Clean up and save results. + */ + void Terminate(); + + void compute(std::vector &val, std::vector &err); + + namespace PrintTable { + void Init(); + void Settings(); + void Header() ; + void Bounds(bool use_full_bound=false) ; + void Result(const Term &term,bool printGrandTotal=false) ; + void ResultSubTotal(bool is_grandtotal=false) ; + void ResultGrandTotal() ; + void Footer() ; + } + /** @} */ + + /** + * @brief Class for keeping information about active term. + * + * This class contains name, description and function to be called for + * selected term. Terms are then stored in TermList and looped in main + * program. + */ + struct Term { + String name = "dummy"; //!< Name of term will be used in header of table. + String description = ""; //!< Description is used while calling \ref Print function. + bool isVegas = true; //!< If term is not Vegas fill result. /** - * @brief Initialization of program. + * @brief Pointer to integration function. This par * - * It parse command line and input file and set interfaced values. It's - * also calling initialization of submodules. + * This will be called within \ref RunIntegration function. */ - void Init(int argc, char * argv[]); - /** - * @brief Initialization of submodules. - */ - void init_params(); + void (*integrate)(VecDbl &val,double &err) = NULL; - /** - * @brief Warming up integration. - * - * Some of terms needed to be pre-run before actual integration. This done - * inside this function. It also prints out current integration settings. - */ - void WarmUp(); + double total_int = 0; //!< Total cross-section summed from all bins. + double total_err2 = 0; //!< Squared uncertainties summed from all bins. + double total_time = 0; //!< Total time spend for all bins. + VecDbl last_int = {}; //!< Here is last cross-section stored for all variations (PDF). + double last_err2 =0; //!< Uncertainty of last integration. + double last_time =0; //!< Time spend in last iteration. /** - * @brief Set integration bounds. - * - * The values from Boundaries are read and provided to \ref phasespace. + * @brief Main functionality of this class. * - * @attention This needs to be called before calling the \ref RunIntegration. + * This will call integration, measure time for processing, store and + * cumulate the result. */ - void SetBounds(BoundIterator); + void RunIntegration(); /** - * @brief Clean up and save results. - */ - void Terminate(); - - namespace PrintTable { - void Init(); - void Settings(); - void Header() ; - void Bounds(bool use_full_bound=false) ; - void Result(const Term &term,bool printGrandTotal=false) ; - void ResultSubTotal(bool is_grandtotal=false) ; - void ResultGrandTotal() ; - void Footer() ; - } - /** @} */ - - /** - * @brief Class for keeping information about active term. + * @brief Print settings of this term to screen. * - * This class contains name, description and function to be called for - * selected term. Terms are then stored in TermList and looped in main - * program. + * This is used while printing \ref IntegrationSettings and format + * follow 4 column mode. */ - struct Term { - String name = "dummy"; //!< Name of term will be used in header of table. - String description = ""; //!< Description is used while calling \ref Print function. - bool isVegas = true; //!< If term is not Vegas fill result. - - /** - * @brief Pointer to integration function. This par - * - * This will be called within \ref RunIntegration function. - */ - void (*integrate)(VecDbl &val,double &err) = NULL; - - double total_int = 0; //!< Total cross-section summed from all bins. - double total_err2 = 0; //!< Squared uncertainties summed from all bins. - double total_time = 0; //!< Total time spend for all bins. - VecDbl last_int = {}; //!< Here is last cross-section stored for all variations (PDF). - double last_err2 =0; //!< Uncertainty of last integration. - double last_time =0; //!< Time spend in last iteration. - - /** - * @brief Main functionality of this class. - * - * This will call integration, measure time for processing, store and - * cumulate the result. - */ - void RunIntegration(); - - /** - * @brief Print settings of this term to screen. - * - * This is used while printing \ref IntegrationSettings and format - * follow 4 column mode. - */ - void Print(); - - //! Overloading stream operator to set description. - template Term & operator<<(const Streamable &data); - - //! Reset to zero values of last_int, last_err2 and last_time - void last_reset(); + void Print(); + + //! Overloading stream operator to set description. + template Term & operator<<(const Streamable &data); + + //! Reset to zero values of last_int, last_err2 and last_time + void last_reset(); + }; + + //! Helper instance for summing results from all terms. + extern Term subtotal; + + //! Container class for Terms + typedef std::vector TermList; + + /** + * @brief Helper instance storing currenlty active terms. + * + * This is where DYTurbo stores active terms. They are looped by \ref + * TermIterator. + */ + extern TermList ActiveTerms; + + /** + * @brief Helper struct for looping active terms. + * + * Term Iterator always loops instance \ref ActiveTerms from beginning. + */ + struct TermIterator { + TermIterator(); //!< By construction always starts at begining of ActiveTerms. + size_t icurrent; //!< Storing position in vector. + bool IsEnd(); //!< Test iterator is in the end. + TermIterator& operator++(); //! Increase operator simple increases \ref icurrent variable. + Term & operator*(); //!< Dereferencing operator uses `vector::operator[]` + }; + + + + //! Container of boundary values for one variable. + typedef VecDbl BoundaryValues; + //! Iterator of boundary values for one variable. + typedef BoundaryValues::iterator BoundValueItr; + + /** + * @brief Holder of boundaries for one variable + */ + struct Boundaries{ + std::string name =""; //!< Name of variable for printing purpose. + BoundaryValues data = {}; //!< Actual values of boundaries for this variable. + + inline BoundValueItr begin() { return data.begin();}; //!< Iterator interface to data. + inline BoundValueItr end() { return data.end(); }; //!< Iterator interface to data. + inline double front() { return data.front();}; //!< Iterator interface to data. + inline double back() { return data.back(); }; //!< Iterator interface to data. + inline size_t size() { return data.size(); }; //!< Iterator interface to data. + }; + + /** + * @brief Define position of variable inside \ref ActiveBoundaries + * + * When adding new variable please also add filling in \ref AddBoundaries + * and interface to phasespace boundaries in \ref SetBounds. + * + * @note Trick is to define one extra enum item in the end for counting number of + * defined items. + * + * @attention The `N_boundaries` must be always the last item. + * + * @todo b_Phi, b_LepPt + */ + enum BoundaryIndex + { + b_M=0, //!< Vector boson invariant mass + b_Y, //!< Vector boson rapidity + b_QT, //!< Vector boson transverse momentum + b_CsTh, //!< Cosine of longitudinal angle in Collins-Soper frame + N_boundaries //! This here to count number of boundaries. }; - //! Helper instance for summing results from all terms. - extern Term subtotal; - - //! Container class for Terms - typedef std::vector TermList; - - /** - * @brief Helper instance storing currenlty active terms. - * - * This is where DYTurbo stores active terms. They are looped by \ref - * TermIterator. - */ - extern TermList ActiveTerms; + /** + * @brief Container of all variable boundaries. + * + * Position of variable is set by BoundaryIndex. This is filled inside function \ref AddBoundaries. + */ + typedef std::vector BoundariesList; + + /** + * @brief Helper instance containing active boundaries. + * + * This is looped by BoundIterator. + */ + extern BoundariesList ActiveBoundaries; + + /** + * @brief Container of boundary value iterators + */ + typedef std::vector BoundValIterList; + + + /** + * @brief Iterating over all variable boundaries (bins) for integration. + */ + struct BoundIterator { + BoundIterator(); //!< After construction always point to first boundary. + bool IsEnd(); //!< Check we already looped through all boundaries. /** - * @brief Helper struct for looping active terms. + * @brief Go to next kinematic boundary. * - * Term Iterator always loops instance \ref ActiveTerms from beginning. - */ - struct TermIterator { - TermIterator(); //!< By construction always starts at begining of ActiveTerms. - size_t icurrent; //!< Storing position in vector. - bool IsEnd(); //!< Test iterator is in the end. - TermIterator& operator++(); //! Increase operator simple increases \ref icurrent variable. - Term & operator*(); //!< Dereferencing operator uses `vector::operator[]` - }; - - - - //! Container of boundary values for one variable. - typedef VecDbl BoundaryValues; - //! Iterator of boundary values for one variable. - typedef BoundaryValues::iterator BoundValueItr; - - /** - * @brief Holder of boundaries for one variable + * This function assures that all combinations of boundaries are taken. + * For more detail see implementation. */ - struct Boundaries{ - std::string name =""; //!< Name of variable for printing purpose. - BoundaryValues data = {}; //!< Actual values of boundaries for this variable. - - inline BoundValueItr begin() { return data.begin();}; //!< Iterator interface to data. - inline BoundValueItr end() { return data.end(); }; //!< Iterator interface to data. - inline double front() { return data.front();}; //!< Iterator interface to data. - inline double back() { return data.back(); }; //!< Iterator interface to data. - inline size_t size() { return data.size(); }; //!< Iterator interface to data. - }; + BoundIterator& operator++(); - /** - * @brief Define position of variable inside \ref ActiveBoundaries - * - * When adding new variable please also add filling in \ref AddBoundaries - * and interface to phasespace boundaries in \ref SetBounds. - * - * @note Trick is to define one extra enum item in the end for counting number of - * defined items. - * - * @attention The `N_boundaries` must be always the last item. - * - * @todo b_Phi, b_LepPt - */ - enum BoundaryIndex { - b_M=0, //!< Vector boson invariant mass - b_Y, //!< Vector boson rapidity - b_QT, //!< Vector boson transverse momentum - b_CsTh, //!< Cosine of longitudinal angle in Collins-Soper frame - N_boundaries //! This here to count number of boundaries. - }; + //! Print to screen. Used by `PrintTable::Boundary`. + void Print(); /** - * @brief Container of all variable boundaries. - * - * Position of variable is set by BoundaryIndex. This is filled inside function \ref AddBoundaries. + * @brief Current lower boundary. + * @param ib Index of variable (\ref BoundaryIndex can be used as input) + * @return Lower boundary of selected variable. */ - typedef std::vector BoundariesList; + inline double loBound(size_t ib){return *current[ib] ;} /** - * @brief Helper instance containing active boundaries. - * - * This is looped by BoundIterator. + * @brief Current upper boundary. + * @param ib Index of variable (\ref BoundaryIndex can be used as input) + * @return Upper boundary of selected variable. */ - extern BoundariesList ActiveBoundaries; + inline double hiBound(size_t ib){return *(current[ib]+1) ;} /** - * @brief Container of boundary value iterators + * @brief List of pointers to all variable boundary values. */ - typedef std::vector BoundValIterList; - - + BoundValIterList current; + /** - * @brief Iterating over all variable boundaries (bins) for integration. + * @brief Control flag. + * + * Set to true in beginning and after first increment is changed to + * false. */ - struct BoundIterator { - BoundIterator(); //!< After construction always point to first boundary. - bool IsEnd(); //!< Check we already looped through all boundaries. - - /** - * @brief Go to next kinematic boundary. - * - * This function assures that all combinations of boundaries are taken. - * For more detail see implementation. - */ - BoundIterator& operator++(); - - //! Print to screen. Used by `PrintTable::Boundary`. - void Print(); - - /** - * @brief Current lower boundary. - * @param ib Index of variable (\ref BoundaryIndex can be used as input) - * @return Lower boundary of selected variable. - */ - inline double loBound(size_t ib){return *current[ib] ;} - - /** - * @brief Current upper boundary. - * @param ib Index of variable (\ref BoundaryIndex can be used as input) - * @return Upper boundary of selected variable. - */ - inline double hiBound(size_t ib){return *(current[ib]+1) ;} - - /** - * @brief List of pointers to all variable boundary values. - */ - BoundValIterList current; - - /** - * @brief Control flag. - * - * Set to true in beginning and after first increment is changed to - * false. - */ - bool isFirst; - }; + bool isFirst; + }; - //! Helper bounds: remember last bounds for printing. - extern BoundIterator last_bounds; - - - namespace PrintTable{ - //! Helper structs for printing: Four column - const int colw1 = 25; - const int colw2 = 20; - const int colw3 = 15; - const int colw4 = 12; - - struct Col4 { - String data; - template Col4( S1 col1, S2 col2, S3 col3, S4 col4, int prec=6){ - SStream tmp; - tmp << setprecision(prec) << setw(colw1) << col1; - tmp << setprecision(prec) << setw(colw2) << col2; - tmp << setprecision(prec) << setw(colw3) << col3; - tmp << setprecision(prec) << setw(colw4) << col4; - tmp << '\n'; - data = tmp.str(); - } - }; - inline std::ostream & operator<< (std::ostream & strm, const Col4 &col){ strm << col.data; return strm; } - - //! Helper structs for printing: Four column, skip first - struct Col3{ - String data; - template Col3(S2 col2, S3 col3, S4 col4){ - SStream tmp; - tmp << setw(colw2) << col2; - tmp << setw(colw3) << col3; - tmp << setw(colw4) << col4; - tmp << '\n'; - data = tmp.str(); - } - }; - inline std::ostream & operator<< (std::ostream & strm, const Col3 &col){ strm << col.data; return strm; } - } - + //! Helper bounds: remember last bounds for printing. + extern BoundIterator last_bounds; + + + namespace PrintTable{ + //! Helper structs for printing: Four column + const int colw1 = 25; + const int colw2 = 20; + const int colw3 = 15; + const int colw4 = 12; + + struct Col4 { + String data; + template Col4( S1 col1, S2 col2, S3 col3, S4 col4, int prec=6){ + SStream tmp; + tmp << setprecision(prec) << setw(colw1) << col1; + tmp << setprecision(prec) << setw(colw2) << col2; + tmp << setprecision(prec) << setw(colw3) << col3; + tmp << setprecision(prec) << setw(colw4) << col4; + tmp << '\n'; + data = tmp.str(); + } + }; + inline std::ostream & operator<< (std::ostream & strm, const Col4 &col){ strm << col.data; return strm; } + + //! Helper structs for printing: Four column, skip first + struct Col3{ + String data; + template Col3(S2 col2, S3 col3, S4 col4){ + SStream tmp; + tmp << setw(colw2) << col2; + tmp << setw(colw3) << col3; + tmp << setw(colw4) << col4; + tmp << '\n'; + data = tmp.str(); + } + }; + inline std::ostream & operator<< (std::ostream & strm, const Col3 &col){ strm << col.data; return strm; } + } } #endif /* ifndef dyturbo_H */ diff --git a/src/gaussrules.C b/src/gaussrules.C index 7ae0be7..ab1b29f 100644 --- a/src/gaussrules.C +++ b/src/gaussrules.C @@ -1,329 +1,331 @@ #include "gaussrules.h" #include "sandia_rules.hpp" //nodes and weights for the gaussian quadrature rules //from https://pomax.github.io/bezierinfo/legendre-gauss.html double gr::xxx[GRNMAX][GRNMAX]; double gr::www[GRNMAX][GRNMAX]; const double gr::xxx2[2]={-0.5773502691896257,0.5773502691896257}; const double gr::www2[2]={1.0000000000000000,1.0000000000000000}; const double gr::xxx3[3]={0.0000000000000000,-0.7745966692414834,0.7745966692414834}; const double gr::www3[3]={0.8888888888888888,0.5555555555555556,0.5555555555555556}; const double gr::xxx4[4]={-0.3399810435848563,0.3399810435848563, -0.8611363115940526,0.8611363115940526}; const double gr::www4[4]={0.6521451548625461,0.6521451548625461, 0.3478548451374538,0.3478548451374538}; const double gr::xxx5[5]={0.0000000000000000,-0.5384693101056831, 0.5384693101056831,-0.9061798459386640, 0.9061798459386640}; const double gr::www5[5]={0.5688888888888889,0.4786286704993665, 0.4786286704993665,0.2369268850561891, 0.2369268850561891}; const double gr::xxx8[8]={-0.1834346424956498,0.1834346424956498, -0.5255324099163290,0.5255324099163290, -0.7966664774136267,0.7966664774136267, -0.9602898564975363,0.9602898564975363}; const double gr::www8[8]={0.3626837833783620,0.3626837833783620, 0.3137066458778873,0.3137066458778873, 0.2223810344533745,0.2223810344533745, 0.1012285362903763,0.1012285362903763}; const double gr::xxx10[10]={-0.1488743389816312,0.1488743389816312, -0.4333953941292472,0.4333953941292472, -0.6794095682990244,0.6794095682990244, -0.8650633666889845,0.8650633666889845, -0.9739065285171717,0.9739065285171717}; const double gr::www10[10]={0.2955242247147529,0.2955242247147529, 0.2692667193099963,0.2692667193099963, 0.2190863625159820,0.2190863625159820, 0.1494513491505806,0.1494513491505806, 0.0666713443086881,0.0666713443086881}; const double gr::www20[20]={0.1527533871307258,0.1527533871307258, 0.1491729864726037,0.1491729864726037, 0.1420961093183820,0.1420961093183820, 0.1316886384491766,0.1316886384491766, 0.1181945319615184,0.1181945319615184, 0.1019301198172404,0.1019301198172404, 0.0832767415767048,0.0832767415767048, 0.0626720483341091,0.0626720483341091, 0.0406014298003869,0.0406014298003869, 0.0176140071391521,0.0176140071391521}; const double gr::xxx20[20]={-0.0765265211334973,0.0765265211334973, -0.2277858511416451,0.2277858511416451, -0.3737060887154195,0.3737060887154195, -0.5108670019508271,0.5108670019508271, -0.6360536807265150,0.6360536807265150, -0.7463319064601508,0.7463319064601508, -0.8391169718222188,0.8391169718222188, -0.9122344282513259,0.9122344282513259, -0.9639719272779138,0.9639719272779138, -0.9931285991850949,0.9931285991850949}; const double gr::xxx24[24]={-0.0640568928626056,0.0640568928626056, -0.1911188674736163,0.1911188674736163, -0.3150426796961634,0.3150426796961634, -0.4337935076260451,0.4337935076260451, -0.5454214713888396,0.5454214713888396, -0.6480936519369755,0.6480936519369755, -0.7401241915785544,0.7401241915785544, -0.8200019859739029,0.8200019859739029, -0.8864155270044011,0.8864155270044011, -0.9382745520027328,0.9382745520027328, -0.9747285559713095,0.9747285559713095, -0.9951872199970213,0.9951872199970213}; const double gr::www24[24]={0.1279381953467522,0.1279381953467522, 0.1258374563468283,0.1258374563468283, 0.1216704729278034,0.1216704729278034, 0.1155056680537256,0.1155056680537256, 0.1074442701159656,0.1074442701159656, 0.0976186521041139,0.0976186521041139, 0.0861901615319533,0.0861901615319533, 0.0733464814110803,0.0733464814110803, 0.0592985849154368,0.0592985849154368, 0.0442774388174198,0.0442774388174198, 0.0285313886289337,0.0285313886289337, 0.0123412297999872,0.0123412297999872}; const double gr::xxx40[40]={-0.0387724175060508,0.0387724175060508, -0.1160840706752552,0.1160840706752552, -0.1926975807013711,0.1926975807013711, -0.2681521850072537,0.2681521850072537, -0.3419940908257585,0.3419940908257585, -0.4137792043716050,0.4137792043716050, -0.4830758016861787,0.4830758016861787, -0.5494671250951282,0.5494671250951282, -0.6125538896679802,0.6125538896679802, -0.6719566846141796,0.6719566846141796, -0.7273182551899271,0.7273182551899271, -0.7783056514265194,0.7783056514265194, -0.8246122308333117,0.8246122308333117, -0.8659595032122595,0.8659595032122595, -0.9020988069688743,0.9020988069688743, -0.9328128082786765,0.9328128082786765, -0.9579168192137917,0.9579168192137917, -0.9772599499837743,0.9772599499837743, -0.9907262386994570,0.9907262386994570, -0.9982377097105593,0.9982377097105593}; const double gr::www40[40]={0.0775059479784248,0.0775059479784248, 0.0770398181642480,0.0770398181642480, 0.0761103619006262,0.0761103619006262, 0.0747231690579683,0.0747231690579683, 0.0728865823958041,0.0728865823958041, 0.0706116473912868,0.0706116473912868, 0.0679120458152339,0.0679120458152339, 0.0648040134566010,0.0648040134566010, 0.0613062424929289,0.0613062424929289, 0.0574397690993916,0.0574397690993916, 0.0532278469839368,0.0532278469839368, 0.0486958076350722,0.0486958076350722, 0.0438709081856733,0.0438709081856733, 0.0387821679744720,0.0387821679744720, 0.0334601952825478,0.0334601952825478, 0.0279370069800234,0.0279370069800234, 0.0222458491941670,0.0222458491941670, 0.0164210583819079,0.0164210583819079, 0.0104982845311528,0.0104982845311528, 0.0045212770985332,0.0045212770985332}; const double gr::xxx50[50]={-0.0310983383271889,0.0310983383271889, -0.0931747015600861,0.0931747015600861, -0.1548905899981459,0.1548905899981459, -0.2160072368760418,0.2160072368760418, -0.2762881937795320,0.2762881937795320, -0.3355002454194373,0.3355002454194373, -0.3934143118975651,0.3934143118975651, -0.4498063349740388,0.4498063349740388, -0.5044581449074642,0.5044581449074642, -0.5571583045146501,0.5571583045146501, -0.6077029271849502,0.6077029271849502, -0.6558964656854394,0.6558964656854394, -0.7015524687068222,0.7015524687068222, -0.7444943022260685,0.7444943022260685, -0.7845558329003993,0.7845558329003993, -0.8215820708593360,0.8215820708593360, -0.8554297694299461,0.8554297694299461, -0.8859679795236131,0.8859679795236131, -0.9130785566557919,0.9130785566557919, -0.9366566189448780,0.9366566189448780, -0.9566109552428079,0.9566109552428079, -0.9728643851066920,0.9728643851066920, -0.9853540840480058,0.9853540840480058, -0.9940319694320907,0.9940319694320907, -0.9988664044200710,0.9988664044200710}; const double gr::www50[50]={0.0621766166553473,0.0621766166553473, 0.0619360674206832,0.0619360674206832, 0.0614558995903167,0.0614558995903167, 0.0607379708417702,0.0607379708417702, 0.0597850587042655,0.0597850587042655, 0.0586008498132224,0.0586008498132224, 0.0571899256477284,0.0571899256477284, 0.0555577448062125,0.0555577448062125, 0.0537106218889962,0.0537106218889962, 0.0516557030695811,0.0516557030695811, 0.0494009384494663,0.0494009384494663, 0.0469550513039484,0.0469550513039484, 0.0443275043388033,0.0443275043388033, 0.0415284630901477,0.0415284630901477, 0.0385687566125877,0.0385687566125877, 0.0354598356151462,0.0354598356151462, 0.0322137282235780,0.0322137282235780, 0.0288429935805352,0.0288429935805352, 0.0253606735700124,0.0253606735700124, 0.0217802431701248,0.0217802431701248, 0.0181155607134894,0.0181155607134894, 0.0143808227614856,0.0143808227614856, 0.0105905483836510,0.0105905483836510, 0.0067597991957454,0.0067597991957454, 0.0029086225531551,0.0029086225531551}; const double gr::xxx64[64]={-0.0243502926634244,0.0243502926634244, -0.0729931217877990,0.0729931217877990, -0.1214628192961206,0.1214628192961206, -0.1696444204239928,0.1696444204239928, -0.2174236437400071,0.2174236437400071, -0.2646871622087674,0.2646871622087674, -0.3113228719902110,0.3113228719902110, -0.3572201583376681,0.3572201583376681, -0.4022701579639916,0.4022701579639916, -0.4463660172534641,0.4463660172534641, -0.4894031457070530,0.4894031457070530, -0.5312794640198946,0.5312794640198946, -0.5718956462026340,0.5718956462026340, -0.6111553551723933,0.6111553551723933, -0.6489654712546573,0.6489654712546573, -0.6852363130542333,0.6852363130542333, -0.7198818501716109,0.7198818501716109, -0.7528199072605319,0.7528199072605319, -0.7839723589433414,0.7839723589433414, -0.8132653151227975,0.8132653151227975, -0.8406292962525803,0.8406292962525803, -0.8659993981540928,0.8659993981540928, -0.8893154459951141,0.8893154459951141, -0.9105221370785028,0.9105221370785028, -0.9295691721319396,0.9295691721319396, -0.9464113748584028,0.9464113748584028, -0.9610087996520538,0.9610087996520538, -0.9733268277899110,0.9733268277899110, -0.9833362538846260,0.9833362538846260, -0.9910133714767443,0.9910133714767443, -0.9963401167719553,0.9963401167719553, -0.9993050417357722,0.9993050417357722}; const double gr::www64[64]={0.0486909570091397,0.0486909570091397, 0.0485754674415034,0.0485754674415034, 0.0483447622348030,0.0483447622348030, 0.0479993885964583,0.0479993885964583, 0.0475401657148303,0.0475401657148303, 0.0469681828162100,0.0469681828162100, 0.0462847965813144,0.0462847965813144, 0.0454916279274181,0.0454916279274181, 0.0445905581637566,0.0445905581637566, 0.0435837245293235,0.0435837245293235, 0.0424735151236536,0.0424735151236536, 0.0412625632426235,0.0412625632426235, 0.0399537411327203,0.0399537411327203, 0.0385501531786156,0.0385501531786156, 0.0370551285402400,0.0370551285402400, 0.0354722132568824,0.0354722132568824, 0.0338051618371416,0.0338051618371416, 0.0320579283548516,0.0320579283548516, 0.0302346570724025,0.0302346570724025, 0.0283396726142595,0.0283396726142595, 0.0263774697150547,0.0263774697150547, 0.0243527025687109,0.0243527025687109, 0.0222701738083833,0.0222701738083833, 0.0201348231535302,0.0201348231535302, 0.0179517157756973,0.0179517157756973, 0.0157260304760247,0.0157260304760247, 0.0134630478967186,0.0134630478967186, 0.0111681394601311,0.0111681394601311, 0.0088467598263639,0.0088467598263639, 0.0065044579689784,0.0065044579689784, 0.0041470332605625,0.0041470332605625, 0.0017832807216964,0.0017832807216964}; void gr::init() { for (int i = 0; i < 64; i++) for (int j = 0; j < 64; j++) { xxx[i][j] = 0; www[i][j] = 0; } for (int i = 0; i < 64; i++) { if (i < 2) xxx[2-1][i] = xxx2[i]; if (i < 3) xxx[3-1][i] = xxx3[i]; if (i < 4) xxx[4-1][i] = xxx4[i]; if (i < 5) xxx[5-1][i] = xxx5[i]; if (i < 8) xxx[8-1][i] = xxx8[i]; if (i < 10) xxx[10-1][i] = xxx10[i]; if (i < 20) xxx[20-1][i] = xxx20[i]; if (i < 24) xxx[24-1][i] = xxx24[i]; if (i < 40) xxx[40-1][i] = xxx40[i]; if (i < 50) xxx[50-1][i] = xxx50[i]; if (i < 64) xxx[64-1][i] = xxx64[i]; if (i < 2) www[2-1][i] = www2[i]; if (i < 3) www[3-1][i] = www3[i]; if (i < 4) www[4-1][i] = www4[i]; if (i < 5) www[5-1][i] = www5[i]; if (i < 8) www[8-1][i] = www8[i]; if (i < 10) www[10-1][i] = www10[i]; if (i < 20) www[20-1][i] = www20[i]; if (i < 24) www[24-1][i] = www24[i]; if (i < 40) www[40-1][i] = www40[i]; if (i < 50) www[50-1][i] = www50[i]; if (i < 64) www[64-1][i] = www64[i]; } /* //generation of weights and nodes double eps = 1e-14; int i2; double s; for (int n = 1; n <= nmax; n++) { double *x = new double[n+1]; double *w1 = new double[n+1]; double *w2 = new double[n+1]; kronrod (n, eps, x, w1, w2); for ( int i = 1; i <= n; i++ ) { int i2; double s; if ( 2 * i <= n + 1 ) { i2 = 2 * i; s = -1.0; } else { i2 = 2 * ( n + 1 ) - 2 * i; s = +1.0; } xxx[n-1][i-1] = s * x[i2-1]; www[n-1][i-1] = w2[i2-1]; } } */ for (int n = 1; n <= GRNMAX; n++) { double *w = new double[n]; double *x = new double[n]; webbur::legendre_compute(n, x, w); for ( int i = 1; i <= n; i++ ) { xxx[n-1][i-1] = x[i-1]; www[n-1][i-1] = w[i-1]; } + delete[] w; + delete[] x; } } diff --git a/src/init.C b/src/init.C index 9bb34d2..fea8ed7 100644 --- a/src/init.C +++ b/src/init.C @@ -1,102 +1,132 @@ #include "dyturbo.h" #include "banner.h" #include "settings.h" #include "cubacall.h" #include "interface.h" #include "coupling.h" #include "propagator.h" #include "pdf.h" #include "switch.h" #include "itilde.h" #include "HistoHandler.h" #include "Kinematics.h" #include "dyres_interface.h" #include "mcfm_interface.h" #include "gaussrules.h" #include "clenshawcurtisrules.h" //#include "chebyshev.h" #include "pdfevol.h" #include "mellinint.h" #include "mesq.h" #include "rapint.h" #include "resint.h" #include "pegasus.h" #include "anomalous.h" #include "resconst.h" #include "vjint.h" #include "vjloint.h" #include "abint.h" #include #include -void DYTurbo::Init( int argc, char * argv[]){ - banner(); - gaussinit_(); //initialisation of fortran gaussian quadrature nodes and weights - coupling::SMparameters(); //initialisation of unused MCFM parameters - // parsing options from input file - opts.parse_options(argc,argv); - PrintTable::Init(); - init_params(); - HistoHandler::Init(); - Kinematics::init(); - /***********************************/ - //print out EW and QCD parameters and other settings - if (opts.verbose) opts.dumpAll(); - PrintTable::Settings(); - /***********************************/ +void DYTurbo::Init( int argc, char * argv[]) +{ + //Should improve the flow: + // 1) init_const + // 2) parse options and input file to know the value of the silent option. Exit with output if options are wrong, print banner if --help is requested + // 3) print banner + // 4) any other printout from option parsing + // ... + + //Print DYTurbo banner + //if (!opts.silent) banner(); + banner(); + + //Initialisation + init_const(); //Initialisation which does not depend on input file + opts.parse_options(argc,argv); //parse options from command line (and parse input file) + init_params(); //Initialisation which depends on input file settings + if (opts.makehistos) HistoHandler::Init(); //Book hisograms and set root output file name + + //Print out parameters and other settings + if (opts.verbose) opts.dumpAll(); + if (!opts.silent) PrintTable::Settings(); +} + +//Initialize constants +void DYTurbo::init_const() +{ + //Integration initialisation + gaussinit_(); //initialisation of fortran gaussian quadrature nodes and weights + cc::init(); //nodes and weights of Clenshaw-Curtis quadrature rules + gr::init(); //nodes and weights of gaussian quadrature rules + //cheb::init(); //Chebyshev nodes for Lagrange interpolation + itilde::init(); //itilde dequad initialisation + if (!opts.ctcpp) + ctquadinit_(); //alfa beta integration initialisation (fortran CT) + cuba::init(); + + //Physics constants initialisation + coupling::SMparameters(); //initialisation of unused MCFM parameters (HF masses are used in the MCFM alphas function) + resconst::init(); //calculate beta, A and B coefficients + rescinit_(); //Resummation coefficients (fortran common blocks, still used in the Sudakov) + + //Output initialisation + PrintTable::Init(); } /** * @brief Initialize parameters of submodules * * rewritten initialisation functions * * @param _inArg Description of param * @return Description of return. */ void DYTurbo::init_params() { // init filling dofill_.doFill_ = 0; + + //Initialise parameters dyres::init(); mcfm::init(); //This functions calls coupling::init() pdf::init(); //Set up PDFs from LHAPDF, set alphas, and read g from the PDF iniflavreduce_(); //need to call this after nproc_.nproc_ is set coupling::initscales(); //Set up QCD scales in the fortran common blocks and recompute alphas(mu) - cc::init(); //nodes and weights of Clenshaw-Curtis quadrature rules - //cheb::init(); //Chebyshev nodes for Lagrange interpolation prop::init(); //Initialise mass and width used in the propagator + //C++ resum: initialise all the C modules - gr::init(); //nodes and weights of gaussian quadrature rules mellinint::initgauss(); //gaussian quadrature for mellin inversion mesq::init(); //EW couplings for born amplitudes rapint::init(); //allocate memory for the rapidity quadrature - resconst::init(); //calculate beta, A and B coefficients - anomalous::init(); //calculate anomalous dimensions, C1, C2 and gamma coefficients + anomalous::init(); //calculate anomalous dimensions, C1, C2 and gamma coefficients (need to be called after mellinint::initgauss()) pdfevol::init(); //transform the PDF from x- to N-space at the factorisation scale if (!opts.fixedorder) { pegasus::init(); //initialise Pegasus QCD and transform the PDF from x- to N-space at the starting scale - resint::init(); //initialise dequad integration for the bessel integral + resint::init(); //initialise dequad integration for the bessel integral, and resummation parameters } - //end C++ resum + //V+j fixed order initialisation vjint::init(); vjloint::init(); - // + abint::init(); //alfa beta integration initialisation - ctquadinit_(); //alfa beta integration initialisation (fortran CT) switching::init(); //switching function initialisation - itilde::init(); //itilde dequad initialisation - rescinit_(); //Resummation coefficients (fortran common blocks) - - // cuba init - cubacores(opts.cubacores,1000000); //< set number of cores (move this to cubainit) - cubainit((void (*)()) initfun,NULL); //< merge at the end of the run - cubaexit((void (*)()) exitfun,NULL); //< merge at the end of the run - // histogram output + Kinematics::init(); //precompute kinematic cuts transformations } +//Free memory allocated by init_params +void DYTurbo::release() +{ + mellinint::release(); + rapint::release(); + anomalous::release(); + pdfevol::release(); + vjint::release(); + abint::release(); +} diff --git a/src/main.C b/src/main.C index f4f2f05..94a5acf 100644 --- a/src/main.C +++ b/src/main.C @@ -1,37 +1,46 @@ #ifndef main_C #define main_C /** * @file main.C * @brief Main program of DYTURBO * * @author Jakub Cuth * @date 2016-09-29 */ #include "dyturbo.h" +#include "settings.h" /** * @brief Main program. * * This is using the DYTurbo namespace to run your calculation. */ int main(int argc, char *argv[]) { - DYTurbo::Init(argc,argv); - DYTurbo::WarmUp(); - DYTurbo::PrintTable::Header(); - for ( DYTurbo::BoundIterator bounds; !bounds.IsEnd(); ++bounds) { + DYTurbo::Init(argc,argv); //Init, read config file + DYTurbo::WarmUp(); //Set up integration terms and bins boundaries + if (!opts.silent) DYTurbo::PrintTable::Header(); + + //Loop on phase space bins + for ( DYTurbo::BoundIterator bounds; !bounds.IsEnd(); ++bounds) + { DYTurbo::SetBounds(bounds); - DYTurbo::PrintTable::Bounds(); - for (DYTurbo::TermIterator term; !term.IsEnd(); ++term){ + if (!opts.silent) DYTurbo::PrintTable::Bounds(); + + //Loop on active terms + for (DYTurbo::TermIterator term; !term.IsEnd(); ++term) + { (*term).RunIntegration(); - DYTurbo::PrintTable::Result((*term)); - } - DYTurbo::PrintTable::ResultSubTotal(); - } - DYTurbo::PrintTable::ResultGrandTotal(); + if (!opts.silent) DYTurbo::PrintTable::Result((*term)); + } + + if (!opts.silent) DYTurbo::PrintTable::ResultSubTotal(); + } + + if (!opts.silent) DYTurbo::PrintTable::ResultGrandTotal(); DYTurbo::Terminate(); return 0; } #endif /* ifndef main_C */ diff --git a/src/pdf.C b/src/pdf.C index 4d3df8a..78276e5 100644 --- a/src/pdf.C +++ b/src/pdf.C @@ -1,229 +1,273 @@ #include "pdf.h" #include "dyres_interface.h" #include "interface.h" #include "scales.h" #include "settings.h" #include #include #include LHAPDF::PDF* pdf::lhapdf = 0; +void (*pdf::xfxq)(const double &x, const double &Q, double *fPDF) = 0; +double (*pdf::alphas)(const double &Q) = 0; + +void pdf::lhaxfxq(const double &x, const double &Q, double *r) +{ + vector fPDF; fPDF.resize(13); + lhapdf->xfxQ(x,Q,fPDF); + copy(fPDF.begin(),fPDF.end(),r); +} + +double pdf::lhaalphas(const double &Q) +{ + return lhapdf->alphasQ(Q); +} + void pdf::init() { - //printf(" ==Initialize PDF set from LHAPDF==\n\n"); - //printf("\n"); - LHAPDF::Info& cfg = LHAPDF::getConfig(); - - cfg.set_entry("Verbosity" , 0 ); - cfg.set_entry("Interpolator" , "logcubic" ); - cfg.set_entry("Extrapolator" , "continuation" ); - cfg.set_entry("ForcePositive" , 0 ); - cfg.set_entry("AlphaS_Type" , "analytic" ); - cfg.set_entry("MZ" , 91.1876 ); - cfg.set_entry("MUp" , 0.002 ); - cfg.set_entry("MDown" , 0.005 ); - cfg.set_entry("MStrange" , 0.10 ); - cfg.set_entry("MCharm" , 1.29 ); - cfg.set_entry("MBottom" , 4.19 ); - cfg.set_entry("MTop" , 172.9 ); - cfg.set_entry("Pythia6LambdaV5Compat" , true ); - - //Old interface - LHAPDF::initPDFSet(opts.LHAPDFset); //LHAPDF::initPDFSetByName(opts.LHAPDFset); - LHAPDF::initPDF(opts.LHAPDFmember); - - //New interface - lhapdf = LHAPDF::mkPDF(opts.LHAPDFset, opts.LHAPDFmember); - - if (opts.PDFerrors && LHAPDF::numberPDF() > 1) + if (!opts.externalpdf) { - opts.totpdf = LHAPDF::numberPDF()+1; - pdferropts_.pdferr_ = true; - pdferropts_.totpdf_ = LHAPDF::numberPDF()+1; + //printf(" ==Initialize PDF set from LHAPDF==\n\n"); + //printf("\n"); + LHAPDF::Info& cfg = LHAPDF::getConfig(); + + cfg.set_entry("Verbosity" , 0 ); + cfg.set_entry("Interpolator" , "logcubic" ); + cfg.set_entry("Extrapolator" , "continuation" ); + cfg.set_entry("ForcePositive" , 0 ); + cfg.set_entry("AlphaS_Type" , "analytic" ); + cfg.set_entry("MZ" , 91.1876 ); + cfg.set_entry("MUp" , 0.002 ); + cfg.set_entry("MDown" , 0.005 ); + cfg.set_entry("MStrange" , 0.10 ); + cfg.set_entry("MCharm" , 1.29 ); + cfg.set_entry("MBottom" , 4.19 ); + cfg.set_entry("MTop" , 172.9 ); + cfg.set_entry("Pythia6LambdaV5Compat" , true ); + + //Old interface + LHAPDF::initPDFSet(opts.LHAPDFset); //LHAPDF::initPDFSetByName(opts.LHAPDFset); + LHAPDF::initPDF(opts.LHAPDFmember); + + //New interface + lhapdf = LHAPDF::mkPDF(opts.LHAPDFset, opts.LHAPDFmember); + + xfxq = lhaxfxq; + alphas = lhaalphas; + + if (opts.PDFerrors && LHAPDF::numberPDF() > 1) + { + opts.totpdf = LHAPDF::numberPDF()+1; + pdferropts_.pdferr_ = true; + pdferropts_.totpdf_ = LHAPDF::numberPDF()+1; + } + else + { + opts.totpdf = 1; + pdferropts_.pdferr_ = false; + pdferropts_.totpdf_ = 1; + } } else { opts.totpdf = 1; pdferropts_.pdferr_ = false; pdferropts_.totpdf_ = 1; } // initialization of alphas setalphas(); // read g from the PDF setg(); //take the cmass and b mass from the PDF // cmass=dsqrt(mcsq) // bmass=dsqrt(mbsq) } //set value of alphas void pdf::setalphas() { + //Old LHAPDF interface //couple_.amz_=LHAPDF::alphasPDF(dymasses_.zmass_); - couple_.amz_ = lhapdf->alphasQ(dymasses_.zmass_); + + //New LHAPDF interface + //couple_.amz_ = lhapdf->alphasQ(dymasses_.zmass_); + + //Allows external alphas + couple_.amz_ = alphas(dymasses_.zmass_); + double scale = fabs(scale_.scale_); if (opts_.approxpdf_ == 1) { int nloop = 3; qcdcouple_.as_=dyalphas_mcfm_(scale,couple_.amz_,nloop); } else //qcdcouple_.as_=dyalphas_lhapdf_(scale); - //qcdcouple_.as_=LHAPDF::alphasPDF(scale); - qcdcouple_.as_=lhapdf->alphasQ(scale); + //qcdcouple_.as_=LHAPDF::alphasPDF(scale); //Old LHAPDF interface + //qcdcouple_.as_=lhapdf->alphasQ(scale); //New LHAPDF interface + qcdcouple_.as_=alphas(scale); //Allows external alphas qcdcouple_.ason2pi_=qcdcouple_.as_/(2*M_PI); qcdcouple_.ason4pi_=qcdcouple_.as_/(4*M_PI); qcdcouple_.gsq_=4*M_PI*qcdcouple_.as_; } //set the value of the g-parameter of the non perturbative form factor void pdf::setg() { LHAPDF::PDFInfo info(opts.LHAPDFset, opts.LHAPDFmember); double gformfactor = info.get_entry_as("g", -1); if (gformfactor >= 0) { cout << "g form factor: input from PDF member: " << gformfactor << endl; opts.g_param = gformfactor; g_param_.g_param_ = gformfactor; np_.g_ = opts.g_param; } } void dysetpdf_(int& member) { + if (opts.externalpdf) return; + if (member == 0) { if (opts.PDFerrors && opts.totpdf > 1) LHAPDF::initPDF(0); else LHAPDF::initPDF(opts.LHAPDFmember); } else LHAPDF::initPDF(member); pdf::setalphas(); // setg(); //set g separately when setting a different PDF in the resummed part } void setmellinpdf_(int &member){ // if member is still same than dont do anything //if (lastMember==member) return; //if (v_mellinpdf.size() 1. || x <= 0.) { for (int i = -MAXNF; i <= MAXNF; i++) fx[MAXNF+i]=0.; return; } - + + //Old LHAPDF interface //double fPDF[13]; //LHAPDF::xfx(x,xmu,fPDF); - vector fPDF; fPDF.resize(13); - pdf::lhapdf->xfxQ(x,xmu,fPDF); + //New LHAPDF interface + //vector fPDF; fPDF.resize(13); + //pdf::lhapdf->xfxQ(x,xmu,fPDF); + + //Allows external PDF + double fPDF[13]; + pdf::xfxq(x,xmu,fPDF); + //vector pids = pdf::lhapdf->flavors(); //for (int i = 0; i < pids.size(); i++) //cout << pids[i] << endl; // cout << endl; // for (int i = -MAXNF; i <= MAXNF; i++) // cout << fPDF[6+i]/x << " "; // cout << endl; //xmu *= xmu; //fPDF[6-5] = pdf::lhapdf->xfxQ(-5,x,xmu); //fPDF[6-4] = pdf::lhapdf->xfxQ(-4,x,xmu); //fPDF[6-3] = pdf::lhapdf->xfxQ(-3,x,xmu); //fPDF[6-2] = pdf::lhapdf->xfxQ(-2,x,xmu); //fPDF[6-1] = pdf::lhapdf->xfxQ(-1,x,xmu); //fPDF[6+0] = pdf::lhapdf->xfxQ(21,x,xmu); //fPDF[6+1] = pdf::lhapdf->xfxQ(1 ,x,xmu); //fPDF[6+2] = pdf::lhapdf->xfxQ(2 ,x,xmu); //fPDF[6+3] = pdf::lhapdf->xfxQ(3 ,x,xmu); //fPDF[6+4] = pdf::lhapdf->xfxQ(4 ,x,xmu); //fPDF[6+5] = pdf::lhapdf->xfxQ(5 ,x,xmu); // for (int i = -MAXNF; i <= MAXNF; i++) // cout << fPDF[6+i]/x << " "; // cout << endl; if (ih == 1) //proton for (int i = -MAXNF; i <= MAXNF; i++) fx[MAXNF+i]=fPDF[6+i]/x; else if (ih == -1) //antiproton for (int i = -MAXNF; i <= MAXNF; i++) fx[MAXNF+i]=fPDF[6-i]/x; //switch off flavours //fx[MAXNF-5]=0.; //bbar //fx[MAXNF-4]=0.; //cbar //fx[MAXNF-3]=0.; //sbar //fx[MAXNF-2]=0.; //fx[MAXNF-1]=0.; //fx[MAXNF+0]=0.; //gluon //fx[MAXNF+1]=0.; //fx[MAXNF+2]=0.; //fx[MAXNF+3]=0.; //s //fx[MAXNF+4]=0.; //c //fx[MAXNF+5]=0.; //b //impose positivity //fx[MAXNF-5]=max(0.,fx[MAXNF-5]); //fx[MAXNF-4]=max(0.,fx[MAXNF-4]); //fx[MAXNF-3]=max(0.,fx[MAXNF-3]); //fx[MAXNF-2]=max(0.,fx[MAXNF-2]); //fx[MAXNF-1]=max(0.,fx[MAXNF-1]); //fx[MAXNF+0]=max(0.,fx[MAXNF+0]); //fx[MAXNF+1]=max(0.,fx[MAXNF+1]); //fx[MAXNF+2]=max(0.,fx[MAXNF+2]); //fx[MAXNF+3]=max(0.,fx[MAXNF+3]); //fx[MAXNF+4]=max(0.,fx[MAXNF+4]); //fx[MAXNF+5]=max(0.,fx[MAXNF+5]); //make u = d and ubar = dbar //fx[MAXNF-1]=fx[MAXNF-2]; //fx[MAXNF+1]=fx[MAXNF+2]; /* if (x < 90./13000.*exp(-1.)) { fx[MAXNF-5]=0.; fx[MAXNF-4]=0.; fx[MAXNF-3]=0.; fx[MAXNF-2]=0.; fx[MAXNF-1]=0.; fx[MAXNF+0]=0.; fx[MAXNF+1]=0.; fx[MAXNF+2]=0.; fx[MAXNF+3]=0.; fx[MAXNF+4]=0.; fx[MAXNF+5]=0.; } */ } diff --git a/src/pdf.h b/src/pdf.h index 6a643a5..c77d407 100644 --- a/src/pdf.h +++ b/src/pdf.h @@ -1,25 +1,31 @@ #ifndef pdf_h #define pdf_h #include #include "mcfm_interface.h" namespace pdf { extern LHAPDF::PDF* lhapdf; extern void init(); extern void setalphas(); extern void setg(); + + extern void (*xfxq)(const double &x, const double &Q, double *fPDF); + extern void lhaxfxq(const double &x, const double &Q, double *fPDF); + + extern double (*alphas)(const double &Q); + extern double lhaalphas(const double &Q); } extern "C" { void fdist_(int& ih, double& x, double& xmu, double fx[2*MAXNF+1]); void dysetpdf_(int& member); void setmellinpdf_(int& member); } #endif diff --git a/src/print_table.C b/src/print_table.C index bd6ea4b..4a29f51 100644 --- a/src/print_table.C +++ b/src/print_table.C @@ -1,593 +1,592 @@ #ifndef print_table_C #define print_table_C /** * @file print_table.C * @brief A brief description * * Detailed description of file * * @author Jakub Cuth , Stefano Camarda * @date 2016-09-29 */ #include "dyturbo.h" #include "settings.h" #include "dyres_interface.h" #include "interface.h" #include "coupling.h" #include "scales.h" #include "HistoHandler.h" #include "clock_real.h" #include #include #include #include #include using std::setw; using std::flush; using std::cout; using std::endl; namespace DYTurbo { namespace PrintTable { SStream textfile("empty", std::ios_base::ate); bool useUnicode; String c_hor; String c_ver; String c_ul; String c_uc; String c_ur; String c_ml; String c_mc; String c_mr; String c_bl; String c_bc; String c_br; size_t eoc; size_t wb; size_t wr; size_t we; size_t wx; size_t wt; size_t bound_width; size_t time_width; size_t term_width; void Init() { useUnicode=opts.unicode; c_hor = useUnicode ? "\u2501" : "-"; c_ver = useUnicode ? "\u2503" : "|"; c_ul = useUnicode ? "\u250f" : "/"; c_uc = useUnicode ? "\u2530" : "-"; c_ur = useUnicode ? "\u2513" : "\\"; c_ml = useUnicode ? "\u2523" : "|"; c_mc = useUnicode ? "\u254b" : "+"; c_mr = useUnicode ? "\u252b" : "|"; c_bl = useUnicode ? "\u2517" : "\\"; c_bc = useUnicode ? "\u253b" : "-"; c_br = useUnicode ? "\u251b" : "/"; eoc=2; //!< end of cell length wb=5; //!< bound length wr=8; //!< result length we=6; //!< error length wx=(useUnicode ? 7 : 5 ); //!< exponent length wt=6; //!< time length bound_width = 2*wb+3; time_width = 2+ // parenthesis wt+ 1; // parenthesis term_width = wr + // result (useUnicode ? 3:4) + // plus minus we + // error wx + // exponenent time_width; } inline void EndOfCell() { std::cout << " " << c_ver << flush; } inline void BeginOfRow() { std::cout << c_ver << flush; } inline void EndOfRow() { cout << endl; } void coutN(size_t N, String s) { for (size_t i = 0; i < N; ++i) { cout << s; }} void Hline(char p='m'){ String left = c_ml; String center = c_mc; String right = c_mr; if (p=='u') { left = c_ul; center = c_uc; right = c_ur; } if (p=='b') { left = c_bl; center = c_bc; right = c_br; } size_t N_loopingBounds =0; for (auto &a: ActiveBoundaries ) if (a.size()>2) N_loopingBounds++; cout << left; size_t wtotal = 1; // begin of line wtotal += (bound_width +eoc)*N_loopingBounds; for (size_t i = 0; i < N_loopingBounds; ++i) { coutN(bound_width+1,c_hor); cout << center; } for (size_t i = 0; i < ActiveTerms.size(); ++i) { coutN(term_width+1,c_hor); cout << center; } // total column coutN(term_width+1,c_hor); cout << right << endl; }; void BoundsAllLooping(bool printNames=false, bool useFullBound=false){ // loop over bounds for (size_t ibound=0; ibound < N_boundaries; ++ibound){ if (ActiveBoundaries[ibound].size()<3) continue; if (printNames){ cout << setw(bound_width) << ActiveBoundaries[ibound].name ; if (opts.texttable) { textfile << ActiveBoundaries[ibound].name << "lo "; textfile << ActiveBoundaries[ibound].name << "hi "; } } else { double lo = useFullBound ? ActiveBoundaries[ibound].front() : last_bounds.loBound(ibound); double hi = useFullBound ? ActiveBoundaries[ibound].back() : last_bounds.hiBound(ibound); cout << setw(wb) << lo ; cout << " - "; cout << setw(wb) << hi ; if (opts.texttable) textfile << lo << " " << hi << " "; } EndOfCell(); } } void SettingsHeader(String title=""); void IntegrationSettings(){ SettingsHeader("Integration settings"); bool fixed_born = opts.doBORN && opts.fixedorder; bool fixed_born_cubature = fixed_born && opts.bornint2d ; bool resum_born = opts.doBORN && !opts.fixedorder; bool resum_born_cubature = resum_born && (opts.resint3d || opts.resint2d); bool ct_cubature = opts.doCT && (opts.ctint2d || opts.ctint3d); cout << Col4 ( "Random seeds" , opts.rseed , "" , "" ) ; cout << Col4 ( "Parallel cores" , opts.cubacores , "" , "" ) ; cout << endl; for (TermIterator iterm;!iterm.IsEnd();++iterm){ (*iterm).Print(); } cout << endl; if (resum_born && opts_.approxpdf_==0){ cout << Col4 ( "Mellin inverse transform:" , "gaussian " , "nodes =" , opts.mellinrule ) ; cout << Col4 ( "" , "" , "intervals =" , opts.mellinintervals ) ; cout << Col4 ( "" , "imaginary axis" , "zmax =" , opts.zmax ) ; } if ( resum_born_cubature || ct_cubature || fixed_born_cubature ){ if (opts.cubaint) cout << Col4( "Angular variables:" , "Suave in dcosth,dphi" , "ncalls =" , opts.suavepoints ); else if (opts.quadint) { cout << Col4( "Angular variable costh:" , "semi-analytical", "ncstart =" , opts.ncstart ); cout << Col4( "Angular variables phi:" , "gaussian" , "intervals =" , opts.phiintervals ); } else if (opts.trapezint) { cout << Col4( "Angular variables costh:" , "semi-analytical" , "ncstart =" , opts.ncstart ); cout << Col4( "Angular variables phi:" , "trapezoidal" , "points =" , opts.nphitrape ); } } cout << endl; string col1 = "Constant boundaries"; for (size_t ibound = 0; ibound < N_boundaries; ++ibound){ if (ActiveBoundaries[ibound].size() > 2) continue; string col2 = ActiveBoundaries[ibound].name; cout << Col4 ( col1 , col2 , "low =" , ActiveBoundaries [ ibound ] .front ( ) ) ; cout << Col4 ( "" , "" , "high =" , ActiveBoundaries [ ibound ] .back ( ) ) ; col1 = ""; } cout << endl; } inline void TermName(Term &term){ cout << setw(term_width) << term.name; EndOfCell(); } void Header() { Hline('u'); BeginOfRow(); if (opts.texttable){ textfile.str("#"); // start of text file textfile.precision(std::numeric_limits::digits10+1); } BoundsAllLooping(true); // print only names for( TermIterator term; !term.IsEnd(); ++term){ TermName(*term); } TermName(subtotal); if (opts.texttable){ for (int ipdf = 0; ipdf < opts.totpdf; ++ipdf) textfile << "PDF" << ipdf << " "; textfile << " uncertainty\n"; } EndOfRow(); Hline(); subtotal.last_reset(); }; void Bounds(bool use_full_bound) { BeginOfRow(); BoundsAllLooping(false,use_full_bound); }; String engineering_base(double value, int dec_max, bool sign){ // Decimal order where we print (==exponent) int decimal_print = (dec_max/3)*3; // Prepare number for printing double fac = pow (10, decimal_print); value/=fac; // Prepare number for printing SStream tmp; // leading sign if (sign && value >=0) tmp << "+"; tmp << value; // if (decimal_print!=0 && value!=0){ // tmp << "e"; // if (decimal_print>0) tmp << "+"; // always print sign on exponent // tmp < 0 && decimal_print < 12 ){ if (decimal_print < 3) tmp << "fb"; else if (decimal_print < 6) tmp << "pb"; else if (decimal_print < 9) tmp << "nb"; else if (decimal_print < 12) tmp << "ub"; } else{ if (decimal_print!=0){ if (useUnicode){ //tmp << " \u00d7"; // mult tmp << " \u00b7"; // dot tmp << "10"; if (decimal_print>0) tmp << "\u207A"; // always print sign on exponent if (decimal_print<0) tmp << "\u207B"; // always print sign on exponent tmp << unicode_exponent(abs(decimal_print)); } else { tmp << " e"; if (decimal_print>0) tmp << "+"; // always print sign on exponent if (decimal_print<0) tmp << "-"; // always print sign on exponent tmp <0) cout << " proton-proton collisions"; cout << " at sqrt(s) = " << energy_.sroot_ << " GeV " << endl; // Order if (opts.fixedorder) { if (nnlo_.order_ == 0) cout << " Computing LO fixed order cross section" << endl; else if (nnlo_.order_ == 1) cout << " Computing NLO fixed order cross section" << endl; else if (nnlo_.order_ == 2) cout << " Computing NNLO fixed order cross section" << endl; } else { if (nnlo_.order_ == 1) cout << " Computing NLO+NLL resummed cross section" << endl; else if (nnlo_.order_ == 2) cout << " Computing NNLO+NNLL resummed cross section" << endl; } // Process if (nproc_.nproc_ == 1) cout << " W+ -> nu(p3)+e+(p4) production " << endl; else if(nproc_.nproc_ == 2) cout << " W- -> e^-(p3)+nu~(p4) production " << endl; else if(nproc_.nproc_== 3 && !opts.useGamma) cout << " Z -> e-(p3)+e+(p4) production " << endl; else if(nproc_.nproc_== 3 && opts.useGamma) cout << " Z/gamma* -> e-(p3)+e+(p4) production " << endl; } void CKMmatrix(){ if (nproc_.nproc_ == 1 || nproc_.nproc_ == 2) { SettingsHeader("CKM matrix"); cout << " | Vud Vus Vub | | " << setw(9) << cabib_.Vud_ << setw(9) << cabib_.Vus_ << setw(9) << cabib_.Vub_ << " | " << endl; cout << " | Vcd Vcs Vcb | = | " << setw(9) << cabib_.Vcd_ << setw(9) << cabib_.Vcs_ << setw(9) << cabib_.Vcb_ << " | " << endl; cout << " | Vtd Vts Vtb | | " << setw(9) << 0 << setw(9) << 0 << setw(9) << 0 << " | " << endl; } } void EWparameters(){ SettingsHeader("EW parameters"); cout << Col4( "" , "Gf =" , ewcouple_.Gf_ , "GeV^-2" , 12); cout << Col4( "" , "1/alpha =" , 1/coupling::aemmz , "" , 12); cout << Col4( "" , "sin(thW)^2 =" , ewcouple_.xw_ , "" , 12); cout << Col4( "" , "W mass =" , dymasses_.wmass_ , "GeV" , 12); cout << Col4( "" , "Z mass =" , dymasses_.zmass_ , "GeV" , 12); cout << Col4( "" , "W width =" , dymasses_.wwidth_ , "GeV" , 12); cout << Col4( "" , "Z width =" , dymasses_.zwidth_ , "GeV" , 12); - cout << Col4( "" , "Narrow width:" , (opts.zerowidth ? "true" : "false") , "" , 16); } void QCDsettings(){ SettingsHeader("QCD settings"); cout << Col4( "Renormalization scale:" , "mur =" , scale_.scale_ , "GeV" ); cout << Col4( "Factorization scale:" , "muf =" , facscale_.facscale_ , "GeV" ); cout << Col4( "Resummation scale:" , "m_ll/Q =" , a_param_.a_param_ , "" ); // cout << Col4( "Renormalization scale:" , String(opts.fmuren ? "dynamic" : "fixed") + " muren =" , opts.kmuren , String("* ") + (opts.dynamicscale ? "m_ll" : to_string(opts.rmass)) ); // cout << Col4( "Factorization scale:" , String(opts.fmufac ? "dynamic" : "fixed") + " mufac =" , opts.kmufac , String("* ") + (opts.dynamicscale ? "m_ll" : to_string(opts.rmass)) ); // cout << Col4( "Resummation scale:" , String(opts.fmures ? "dynamic" : "fixed") + " mures =" , opts.kmures , String("* ") + (opts.dynamicscale ? "m_ll" : to_string(opts.rmass)) ); cout << Col4( "Renormalization scale:" , String(opts.fmuren ? "dynamic" : "fixed") + " muren =" , opts.kmuren , String("* ") + scales::func(opts.fmuren) ); cout << Col4( "Factorization scale:" , String(opts.fmufac ? "dynamic" : "fixed") + " mufac =" , opts.kmufac , String("* ") + scales::func(opts.fmufac) ); cout << Col4( "Resummation scale:" , String(opts.fmures ? "dynamic" : "fixed") + " mures =" , opts.kmures , String("* ") + scales::func(opts.fmures) ); cout << Col4( "Strong coupling" , "alpha_s(MZ) =" , couple_.amz_ , "" ); cout << Col4( "" , "alpha_s(mur) =" , qcdcouple_.as_ , "" ); cout << Col4( "" , "running order =" , (LHAPDF::getOrderAlphaS()+1) , "-loop" ); cout << Col4( "Non-perturbative" , "form factor g =" , g_param_.g_param_ , "GeV^2" ); } void PDFsettings(){ SettingsHeader("PDF settings"); cout << Col4( "" , "PDF set:" , opts.LHAPDFset , "" ); cout << Col4( "" , "PDF member:" , opts.LHAPDFmember , "" ); cout << Col4( "" , "PDF errors:" , (opts.PDFerrors ? "true" : "false") , "" ); if (opts.doBORN && !opts.fixedorder) { if (opts_.approxpdf_ == 1) cout << Col4( "Mellin moments of PDFs:" , "" , "Polynomial interpolation" , "" ); else { cout << Col4( "Mellin moments of PDFs:" , "" , "Numerical integration" , "" ); cout << Col4( "" , "nodes for the quadrature:" , 64 , "" ); cout << Col4( "" , "Intervals for the quadrature:" , opts_.pdfintervals_ , "" ); } } } void QTrecoil(){ SettingsHeader("qT recoil"); if (opts.qtrec_cs) cout << Col4( "qt-recoil prescription:" , "Collins-Soper" , " kt1 = p_V(x)/2; kt2 = p_V(y)/2" , "" ); else if (opts.qtrec_kt0) cout << Col4( "qt-recoil prescription:" , "kt0" , " kt1 = kt2 = 0" , "" ); else if (opts.qtrec_naive) cout << Col4( "qt-recoil prescription:" , "Naive" , " kt = kt_CS * (1+p_V(z)/(m+E_V))" , "" ); } void AppliedCuts(){ SettingsHeader("Cuts"); cout << Col4( "", "apply cuts:" , (opts.makecuts ? "true" : "false") , "" ); if (opts.makecuts){ cout << Col4("" , "pt_l > " , opts.lptcut , "" ); cout << Col4("" , "|eta_l| < " , opts.lycut , "" ); cout << Col4("" , "pt_lep > " , opts.lepptcut , "" ); cout << Col4("" , "|eta_lep| < " , opts.lepycut , "" ); cout << Col4("" , "pt_alep > " , opts.alpptcut , "" ); cout << Col4("" , "|eta_alep| < " , opts.alpycut , "" ); cout << Col4("" , "user cuts: " , "true" , "" ); } } void ResummationDamp(){ if (!opts.fixedorder && ((opts.doBORN && !opts.fixedorder) || opts.doCT)) { SettingsHeader("ResummationDamp"); cout << Col4( "" , "damping mode:" , opts.dampmode , "" ); cout << Col4( "" , "damp above:" , opts.dampk*opts.rmass , "GeV" ); cout << Col4( "" , "damping width:" , opts.dampdelta*opts.rmass , "GeV" ); cout << Col4( "" , "resummation cutoff:" , opts.qtcutoff*1000 , "MeV" ); } } void DebugSettings(){ SettingsHeader("Debug settings"); cout << Col4( "" , "timeprofile:" , (opts.timeprofile ? "true" : "false") , "" ); cout << Col4( "" , "verbose:" , (opts.verbose ? "true" : "false") , "" ); cout << Col4( "" , "cubaverbosity:" , opts.cubaverbosity , "" ); } void Settings(){ ProcessSettings(); CKMmatrix(); EWparameters(); QCDsettings(); PDFsettings(); QTrecoil(); AppliedCuts(); ResummationDamp(); DebugSettings(); SettingsHeader(); // empty header will create line } void Footer() { SettingsHeader("Summary"); VecStr s_res = result_format(subtotal.total_int, sqrt(subtotal.total_err2), true); cout << Col4 ("Total cross section" , "" , s_res[0]+pm()+s_res[1] , s_res[2] ); s_res = time_format(subtotal.total_time, true); cout << Col4 ("Calculation time" , "" , s_res[0] , s_res[1] ); cout << Col4 ("Output file" , "" , HistoHandler::result_filename + HistoHandler::file_suffix , ""); if (opts.texttable){ String name = HistoHandler::result_filename + ".txt"; cout << Col4 ("Result in text file" , "" , name , ""); std::ofstream f (name.c_str(), std::ofstream::trunc); f << textfile.str(); f.close(); } SettingsHeader(); } } } #endif /* ifndef print_table_C */ diff --git a/src/resintegr.C b/src/resintegr.C index ca495e3..72a5e23 100644 --- a/src/resintegr.C +++ b/src/resintegr.C @@ -1,509 +1,510 @@ #include "resintegr.h" #include "omegaintegr.h" #include "phasespace.h" #include "settings.h" #include "interface.h" #include "dyres_interface.h" #include "switch.h" #include "resint.h" #include "rapint.h" #include "cubacall.h" #include "isnan.h" #include "scales.h" #include "pdfevol.h" #include #include #include #include #include "KinematicCuts.h" int resintegrand1d_cubature_v(unsigned ndim, long unsigned npts, const double x[], void *data, unsigned ncomp, double f[]) { #pragma omp parallel for num_threads(opts.cubacores) copyin(a_param_,rlogs_,resint::a,resint::loga,resint::rloga,pdfevol::UVP,pdfevol::DVP,pdfevol::USP,pdfevol::DSP,pdfevol::SSP,pdfevol::GLP,pdfevol::CHP,pdfevol::BOP) for (unsigned i = 0; i < npts; i++) { // evaluate the integrand for npts points double xi[ndim]; double fi[ncomp]; for (unsigned j = 0; j < ndim; j++) xi[j] = x[i*ndim + j]; resintegrand1d(ndim, xi, ncomp, fi); for (unsigned k = 0; k < ncomp; ++k) f[i*ncomp + k] = fi[k]; } return 0; } int resintegrand1d_cubature(unsigned ndim, const double x[], void *data, unsigned ncomp, double f[]) { resintegrand1d(ndim, x, ncomp, f); return 0; } //This integration works only without cuts (!opts.makecuts) integrand_t resintegrand1d(const int &ndim, const double x[], const int &ncomp, double f[]) { tell_to_grid_we_are_alive(); clock_t begin_time, end_time; begin_time = clock(); //Jacobian of the change of variables from the segment [0,1] to qt boundaries double jac = 1.; bool status = true; //Generate the boson invariant mass between the integration boundaries //kinematic limit from the relation x(1,2) < 1 ==> exp(fabs(y)) < sqrt(s)/m //There is also a lower limit from the switching: m > qtmin/opts.dampk double absymn; if (phasespace::ymin*phasespace::ymax <= 0.) absymn = 0.; else absymn = min(fabs(phasespace::ymin),fabs(phasespace::ymax)); double mlim = opts.sroot/exp(absymn); double r1 = {x[0]}; status = phasespace::gen_m(r1, jac, mlim, false, true); if (!status) { f[0] = 0.; return 0; } //Limit the y boundaries to the kinematic limit in y double ylim = 0.5*log(pow(opts.sroot,2)/phasespace::m2); double ymn = min(max(-ylim, phasespace::ymin),ylim); double ymx = max(min(ylim, phasespace::ymax),-ylim); if (ymn >= ymx) { f[0]=0.; return 0; } phasespace::set_phiV(0); //Dynamic scale --> is this still needed? probably it is for the fortran version of the code //if (opts.dynamicscale) //scaleset_(phasespace::m2); scales::set(phasespace::m); scales::mcfm(); clock_t ybt, yet; ybt = clock(); if (!opts.mellin1d) { rapint::allocate(); rapint::integrate(ymn,ymx,phasespace::m); } yet = clock(); //switching cannot be applied because we integrate analitically in pt //double swtch = switching::swtch(phasespace::qt, phasespace::m); //Call the resummed cross section double costh = 0; double y = 0.5*(ymx+ymn); //needed to get the correct IFIT index of the approximate PDF double qt = 0.5*(phasespace::qtmax+phasespace::qtmin); //not needed int mode = 3; clock_t rbt = clock(); f[0]=resint::rint(costh,phasespace::m,qt,y,mode)/(8./3.); clock_t ret = clock(); // cout << "resummation " << f[0] << " m " << phasespace::m << " jac " << jac << endl; if (isnan_ofast(f[0])) f[0]=0.; //avoid nans f[0] = f[0]*jac; end_time = clock(); if (opts.timeprofile) cout << setw (3) << "m" << setw(10) << phasespace::m << setw(4) << "qt" << setw(10) << qt << setw(8) << "result" << setw(10) << f[0] << setw(10) << "tot time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << setw(10) << "rapint" << setw(10) << float( yet - ybt ) / CLOCKS_PER_SEC << setw(10) << "resumm" << setw(10) << float( ret - rbt ) / CLOCKS_PER_SEC << endl; if (!opts.mellin1d) rapint::free(); return 0; } int resintegrand2d_cubature_v(unsigned ndim, long unsigned npts, const double x[], void *data, unsigned ncomp, double f[]) { tell_to_grid_we_are_alive(); //The current issue with openmp parallelisation, is that the resummation integrand has many //global variables, and the use of these variables has a race // cout << "parallel " << npts << endl; #pragma omp parallel for num_threads(opts.cubacores) copyin(a_param_,rlogs_,resint::a,resint::loga,resint::rloga,pdfevol::UVP,pdfevol::DVP,pdfevol::USP,pdfevol::DSP,pdfevol::SSP,pdfevol::GLP,pdfevol::CHP,pdfevol::BOP) for (unsigned i = 0; i < npts; i++) { // int nThreads = omp_get_num_threads(); // printf("Total number of threads: %d\n", nThreads); // evaluate the integrand for npts points double xi[ndim]; double fi[ncomp]; for (unsigned j = 0; j < ndim; j++) xi[j] = x[i*ndim + j]; resintegrand2d(ndim, xi, ncomp, fi); for (unsigned k = 0; k < ncomp; ++k) f[i*ncomp + k] = fi[k]; } return 0; } int resintegrand2d_cubature(unsigned ndim, const double x[], void *data, unsigned ncomp, double f[]) { tell_to_grid_we_are_alive(); resintegrand2d(ndim, x, ncomp, f); return 0; } integrand_t resintegrand2d(const int &ndim, const double x[], const int &ncomp, double f[]) { tell_to_grid_we_are_alive(); clock_t begin_time, end_time; begin_time = clock(); //Jacobian of the change of variables from the unitary hypercube x[3] to the m, y, qt boundaries double jac = 1.; bool status = true; double r2[2] = {x[0], x[1]}; status = phasespace::gen_mqt(r2, jac, false, true); if (!status) { f[0] = 0.; return 0; } //Limit the y boundaries to the kinematic limit in y double ylim = 0.5*log(pow(opts.sroot,2)/phasespace::m2); double ymn = min(max(-ylim, phasespace::ymin),ylim); double ymx = max(min(ylim, phasespace::ymax),-ylim); if (ymn >= ymx) { f[0]=0.; return 0; } phasespace::set_phiV(0); //Dynamic scale --> is this still needed? probably it is for the fortran version of the code //if (opts.dynamicscale) //scaleset_(phasespace::m2); scales::set(phasespace::m); scales::mcfm(); //Perform quadrature rule integration in rapidity and semi-analitical costh, phi_lep integration int nocuts = !opts.makecuts; clock_t ybt, yet; ybt = clock(); //there is a potential issue here, when lepton cuts are applied //the rapidity dependent exponential are cached assuming integration between ymin and ymax //for consistency, has to keep the integration between ymin and ymax if (opts.makecuts) { if (opts.resumcpp) { //C++ resum rapint::allocate(); rapint::integrate(phasespace::ymin,phasespace::ymax,phasespace::m); //end C++ resum } else rapintegrals_(phasespace::ymin,phasespace::ymax,phasespace::m,nocuts); } else { if (opts.resumcpp) { //C++ rewritten resum if (!opts.mellin1d) { rapint::allocate(); rapint::integrate(ymn,ymx,phasespace::m); } //end C++ resum } else rapintegrals_(ymn,ymx,phasespace::m,nocuts); } yet = clock(); //Are the following three lines needed? //phasespace::set_m(m); //phasespace::set_qt(qt); //phasespace::set_phiV(0); //Are the following two lines needed? //phasespace::set_mqtyphi(m, qt, 0); //omegaintegr::genV4p(); // --> not needed, it is regenerated in rapint // SWITCHING FUNCTIONS // double swtch=1.; // if (qt >= m*3/4.) swtch=exp(-pow((m*3/4.-qt),2)/pow((m/2.),2)); // GAUSS SWITCH // if (swtch <= 0.01) swtch = 0; double swtch = switching::swtch(phasespace::qt, phasespace::m); //Call the resummed cross section double costh = 0; double y = 0.5*(ymx+ymn); //needed to get the correct IFIT index of the approximate PDF int mode = 2; clock_t rbt = clock(); /* //No need to check the switching, since the phase space is generated up to the switching qt limit if (swtch < switching::cutoff*switching::tolerance) { f[0]=0.; return 0; } */ if (opts.resumcpp) f[0]=resint::rint(costh,phasespace::m,phasespace::qt,y,mode)/(8./3.); else f[0]=resumm_(costh,phasespace::m,phasespace::qt,y,mode)/(8./3.); clock_t ret = clock(); if (isnan_ofast(f[0])) f[0]=0.; //avoid nans f[0] = f[0]*jac*swtch; end_time = clock(); if (opts.timeprofile) cout << setw (3) << "m" << setw(10) << phasespace::m << setw(4) << "qt" << setw(10) << phasespace::qt << setw(8) << "result" << setw(10) << f[0] << setw(10) << "tot time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << setw(10) << "rapint" << setw(10) << float( yet - ybt ) / CLOCKS_PER_SEC << setw(10) << "resumm" << setw(10) << float( ret - rbt ) / CLOCKS_PER_SEC << endl; if (opts.resumcpp) if (!opts.mellin1d) rapint::free(); return 0; } integrand_t resintegrand3d(const int &ndim, const double x[], const int &ncomp, double f[]) { tell_to_grid_we_are_alive(); clock_t begin_time, end_time; begin_time = clock(); //Jacobian of the change of variables from the unitary hypercube x[3] to the m, y, qt boundaries double jac = 1.; bool status = true; double r[3] = {x[0], x[1], x[2]}; status = phasespace::gen_myqt(r, jac, false, true); //(qtcut = false, qtswitching = true) if (!status) { f[0] = 0.; return 0; } phasespace::set_phiV(0.); //generate boson 4-momentum, with m, qt, y and phi=0 omegaintegr::genV4p(); // SWITCHING FUNCTIONS // double swtch=1.; // if (qt >= m*3/4.) swtch=exp(-pow((m*3/4.-qt),2)/pow((m/2.),2)); // GAUSS SWITCH // if (swtch <= 0.01) swtch = 0; double swtch = switching::swtch(phasespace::qt, phasespace::m); //In this point of phase space (m, qt, y) the costh integration is performed by //calculating the 0, 1 and 2 moments of costh //that are the integrals int(dcosth dphi1 dphi2), int(costh dcosth dphi1 dphi2), and int(costh^2 dcosth dphi1 dphi2) convoluted with cuts //Then the epxressions 1, costh and costh^2 in sigmaij are substituted by these costh moments double costh = 0; int mode = 1; /* //No need to check the switching, since the phase space is generated up to the switching qt limit if (swtch < switching::cutoff*switching::tolerance) { f[0]=0.; return 0; } */ //Dynamic scale //if (opts.dynamicscale) //scaleset_(phasespace::m2); scales::set(phasespace::m); scales::mcfm(); //evaluate the resummed cross section if (opts.resumcpp) f[0]=resint::rint(costh,phasespace::m,phasespace::qt,phasespace::y,mode)/(8./3.); else f[0]=resumm_(costh,phasespace::m,phasespace::qt,phasespace::y,mode)/(8./3.); if (isnan_ofast(f[0])) f[0]=0.; //avoid nans f[0] = f[0]*jac*swtch; end_time = clock(); if (opts.timeprofile) cout << setw (3) << "m" << setw(10) << phasespace::m << setw(4) << "qt" << setw(10) << phasespace::qt << setw(4) << "y" << setw(10) << phasespace::y << setw(8) << "result" << setw(10) << f[0] << setw(10) << "tot time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << endl; return 0; } //Perform the integration as in the original dyres code integrand_t resintegrandMC(const int &ndim, const double x[], const int &ncomp, double f[], void* userdata, const int &nvec, const int &core, double &weight, const int &iter) { tell_to_grid_we_are_alive(); clock_t begin_time, end_time; begin_time = clock(); //Jacobian of the change of variables from the unitary hypercube x[3] to the m, y, qt boundaries double jac = 1.; bool status = true; double r[3] = {x[0], x[1], x[2]}; status = phasespace::gen_myqt(r, jac, false, true); //(qtcut = false, qtswitching = true) if (!status) { f[0] = 0.; return 0; } //generate boson 4-momentum, with m, qt, y, and phi phasespace::set_phiV(-M_PI+2.*M_PI*x[5]); // phasespace::calcexpy(); // phasespace::calcmt(); ///////////////////// //This function set the RF axes according to the selected qt-recoil prescription omegaintegr::genV4p(); //alternative, generate in naive RF, and calculate costh with the selected qt-recoil prescription //phasespace::genRFaxes(phasespace::naive); //phasespace::genV4p(); ///////////////////// double r2[2] = {x[3], x[4]}; phasespace::gen_costhphi(r2, jac); + phasespace::calcphilep(); phasespace::genl4p(); //apply lepton cuts if (opts.makecuts) if (!Kinematics::Cuts::KeepThisEvent(phasespace::p3, phasespace::p4)) { f[0]=0.; return 0; } ///////////////////// double costh_CS = phasespace::costh; //alternative, generate in naive RF, and calculate costh with the selected qt-recoil prescription //double costh_CS = omegaintegr::costh_qtrec(); //cout << phasespace::costh << " " << costh_CS << endl; ///////////////////// double m = phasespace::m; double qt = phasespace::qt; double y = phasespace::y; //Dynamic scale //if (opts.dynamicscale) //scaleset_(phasespace::m2); scales::set(phasespace::m); scales::mcfm(); double psfac = 3./8./2./M_PI; //apply resummation switching double swtch = switching::swtch(qt, m); /* //No need to check the switching, since the phase space is generated up to the switching qt limit if (swtch < switching::cutoff*switching::tolerance) { f[0]=0.; return 0; } */ int mode = 0; /* //skip PDF loop in the preconditioning phase int Npdf = (iter!=last_iter ? 1 : opts.totpdf); for(int ipdf=0; ipdf +//#include double scales::ren; double scales::fac; double scales::res; double scales::ren2; double scales::fac2; double scales::res2; double scales::alphasmz; double scales::alphas; void scales::init() { - //alphasmz = LHAPDF::alphasPDF(coupling::zmass); - alphasmz = pdf::lhapdf->alphasQ(coupling::zmass); + //alphasmz = LHAPDF::alphasPDF(coupling::zmass); //Old LHAPDF interface + //alphasmz = pdf::lhapdf->alphasQ(coupling::zmass); //New LHAPDF interface + alphasmz = pdf::alphas(coupling::zmass); //Allows external alphas } string scales::func(int ff) { string f; switch (ff) { case 0: f = to_string(opts.rmass); break; case 1: f = "m_ll"; break; case 2: f = "sqrt(m_ll^2+p_T^2)"; break; case 3: f = "sqrt(m_ll^2+p_T^2+m_jj^2)"; break; } return f; } void scales::form(double &scale2, int ff, double m, double pt, double mjj) { switch (ff) { case 0: scale2 = pow(opts.rmass,2); break; case 1: scale2 = pow(m,2); break; case 2: scale2 = pow(m,2) + pow(pt,2); break; case 3: scale2 = pow(m,2) + pow(pt,2) + pow(mjj,2); break; } } void scales::set(double m, double pt, double mjj) { //set scales according to the chosen functional form form(ren2, opts.fmuren, m, pt, mjj); form(fac2, opts.fmufac, m, pt, mjj); form(res2, opts.fmures, m); ren = sqrt(ren2); fac = sqrt(fac2); res = sqrt(res2); //Rescale by factors ren *= opts.kmuren; fac *= opts.kmufac; res *= opts.kmures; //catch absurdly large scales double scalemax = 10000.; if (ren > scalemax) {ren = scalemax; ren2 = pow(ren,2);} if (fac > scalemax) {fac = scalemax; fac2 = pow(fac,2);} if (res > scalemax) {res = scalemax; res2 = pow(res,2);} //run alphas if (opts_.approxpdf_ == 1) { int loop = 3; alphas = dyalphas_mcfm_(ren,alphasmz,loop); } else - //alphas = LHAPDF::alphasPDF(ren); - alphas = pdf::lhapdf->alphasQ(ren); + //alphas = LHAPDF::alphasPDF(ren); //Old LHAPDF interface + //alphas = pdf::lhapdf->alphasQ(ren); //New LHAPDF interface + alphas = pdf::alphas(ren); //Allows external alphas } //set mcfm scales and couplings void scales::mcfm() { //Set up QCD scales in the fortran common blocks scale_.scale_ = ren; scale_.musq_ = pow(ren,2); facscale_.facscale_ = fac; //Set alphas and strong coupling in the fortran common blocks qcdcouple_.as_ = alphas; qcdcouple_.ason2pi_ = alphas/(2*M_PI); qcdcouple_.ason4pi_ = alphas/(4*M_PI); qcdcouple_.gsq_= 4*M_PI*alphas; //Set all factorization scales of the dipole contributions to facscale //to avoid problems when dynamicscale=.false. for (int nd =0; nd <= 40; nd++) dipolescale_.dipscale_[nd] = fac; } void scales::dyres(double m) { a_param_.a_param_ = m/res; } //set scales and alpha strong in vjet analytical calculation void scales::vjet() { scales2_.xmur_ = ren; scales2_.xmuf_ = fac; scales2_.xmur2_ = pow(ren,2); scales2_.xmuf2_ = pow(fac,2); asnew_.as_ = alphas/M_PI; asp_.asp_ = alphas; } //Fortran interface void scaleset_mcfm_(double &m, double &pt, double &mjj) { scales::set(m, pt, mjj); scales::mcfm(); scales::dyres(m); } int dynamic_fac_() { return (opts.fmufac > 0); } diff --git a/src/settings.C b/src/settings.C index 4abf339..aef0631 100644 --- a/src/settings.C +++ b/src/settings.C @@ -1,1012 +1,1071 @@ #include #include #include #include #include "settings.h" #include "dyres_interface.h" #include "interface.h" #include "phasespace.h" // CXX option parser: https://raw.githubusercontent.com/jarro2783/cxxopts/master/src/cxxopts.hpp #include "cxxopts.hpp" #include "handy_typdefs.h" settings opts; binning bins; void settings::parse_options(int argc, char* argv[]){ // Declare the supported options. po::Options args(argv[0], " [config.in] \n\n" " Fast Drell-Yan Monte Carlo and quadrature integrator. \n\n" " NOTE: Command line options are overiding the default and config file settings." ); // Hidden arguments args.add_options("Hidden") ("conf_file" , "Name of output file. ", po::value()->default_value("") ) ; // Program options args.add_options("") ("h,help" , "Print this help and die." ) ("v,verbose" , "Be verbose" ) ("q,small-stat" , "Set quick run with small stat." ) ("p,proc" , "Set process [z0/wp/wm]" , po::value() ) ("c,collider" , "Set beam conditions [tev2/lhc7/lhc8/lhc13/lhc14]" , po::value() ) ("o,order" , "Set order [0:LO, 1:NLL+NLO, 2:NNLL+NNLO]" , po::value() ) - ("f,fixedorder" , "Set fixed order" ) + ("f,fixedorder" , "Set fixed order only" ) ("e,resummation" , "Set resummation" ) ("t,term" , "Set term [BORN,CT,VJ,VJREAL,VJVIRT,ALL]" , po::value() ) ("r,seed" , "Set random seed [integer]" , po::value() ) ("s,pdfset" , "Set PDF set [LHAPDF name]" , po::value() ) ("m,pdfvar" , "Set PDF member [integer/all]" , po::value() ) ("g,gparam" , "Set Sudakov paramter" , po::value() ) ("R,kmuren" , "Set realative renormalization scale" , po::value() ) ("F,kmufac" , "Set realative factorization scale" , po::value() ) ("qtbins" , "Set equdistan binning for mass [N,lo,hi]" , po::value() ) ("ybins" , "Set equdistan binning for qt [N,lo,hi]" , po::value() ) ("mbins" , "Set equdistan binning for y [N,lo,hi]" , po::value() ) ("grid" , "Be verbose to avoid jobs being killed") ; // Parse try { args.parse_positional( std::vector({"conf_file"}) ); args.parse(argc,argv); } catch (po::OptionException &e){ printf("%s\n", args.help().c_str()); printf("Bad arguments: %s \n",e.what()); throw e; } // Print help and die if (args.count("help")) { throw QuitProgram(args.help().c_str()); } // load config file (or default settings) readfromfile ( args["conf_file"].as() ); bins.readfromfile ( args["conf_file"].as() ); + externalpdf = false; + + if (opts.redirect) + { + string logfile = output_filename + ".log"; + freopen(logfile.c_str(),"w",stdout); + } + // NOTE: Command line options are overiding the default and config file settings. // verbose if (args.count("verbose")) { verbose=true; cubaverbosity=3; } if (args.count("grid")) { gridverbose=true; cubaverbosity=3; } // rseed if (args.count("seed")) rseed=args["seed"].as(); // order if (args.count("order")) order=args["order"].as(); // fixed order if (args.count("fixedorder")) fixedorder = true; if (args.count("resummation")) fixedorder = false; // small stat if (args.count("small-stat")){ niterBORN = 1; niterCT = 1; niterVJ = 1; vegasncallsBORN = (fixedorder ? 1e5 : 1e3); vegasncallsCT = 1e4; vegasncallsVJLO = 1e5; vegasncallsVJREAL = 1e5; vegasncallsVJVIRT = 1e5; relaccuracy = 0.1; } // proc if (args.count("proc")) { string val=args["proc"].as(); ToLower(val); if (val == "z0"){ nproc=3; } else if (val == "wp"){ nproc=1; } else if (val == "wm"){ nproc=2; } else { throw QuitProgram("Unsupported value of proc: "+val); } } // PDF if (args.count("pdfset")) LHAPDFset=args["pdfset"].as(); if (args.count("pdfvar")) { // set default values PDFerrors=false; LHAPDFmember=0; string val=args["pdfvar"].as(); ToLower(val); if (val=="all") { PDFerrors=true; } else if (IsNumber(val)) { LHAPDFmember=stod(val); } else { throw QuitProgram("Unsupported value of pdfvar: "+val); } } //Gpar if (args.count("gparam")) { opts.g_param = args["gparam"].as(); } if (args.count("kmuren")) { opts.kmuren = args["kmuren"].as(); } if (args.count("kmufac")) { opts.kmufac = args["kmufac"].as(); } // Collider if (args.count("collider")) { string val=args["collider"].as(); ToLower(val); if (val == "tev1" ){ sroot=1.80e3; ih1=1; ih2=-1; } else if (val == "tev2" ){ sroot=1.96e3; ih1=1; ih2=-1; } else if (val == "lhc7" ){ sroot=7.00e3; ih1=1; ih2=1; + } else if (val == "lhc5" ){ sroot=5.00e3; ih1=1; ih2=1; } else if (val == "lhc8" ){ sroot=8.00e3; ih1=1; ih2=1; } else if (val == "lhc13" ){ sroot=13.0e3; ih1=1; ih2=1; } else if (val == "lhc14" ){ sroot=14.0e3; ih1=1; ih2=1; } else { throw QuitProgram("Unsupported value of collider: "+val); } } // term if (args.count("term")) { // first turn off all terms doBORN = doCT = doVJ = doVJREAL = doVJVIRT = false ; string val=args["term"].as(); ToUpper(val); for (auto piece : Tokenize(val)) { if ( piece == "BORN" ) { doBORN = true; } else if ( piece == "CT" ) { doCT = true; } else if ( piece == "VJ" ) { doVJ = true; doVJVIRT = true; doVJREAL = true; } else if ( piece == "VJVIRT" ) { doVJ = true; doVJVIRT = true; } else if ( piece == "VJREAL" ) { doVJ = true; doVJREAL = true; } else if ( piece == "ALL" ) { doBORN = doCT = doVJ = doVJREAL = doVJVIRT = true; } else { throw QuitProgram("Unsupported value of term : "+piece); } } } //binning parse_binning("qtbins" , bins.qtbins ,args); parse_binning("ybins" , bins.ybins ,args); parse_binning("mbins" , bins.mbins ,args); // check consistency of settings check_consitency(); } // PROTOTYPE OF VARIABLE REGISTRATION struct var_def{ string name = ""; void * ptr = NULL; char type = '0'; // 0-group name, b-bool, s-string, i-int, d-doubl, v-VecDbl string dump(){ SStream tmp; if (type == '0') { tmp << "# " << name; } else { tmp << name << " = "; if (type != 'b'){ bool *val = (bool*) ptr; tmp << ((*val) ? "true" : "false"); } if (type != 'd'){ double *val = (double*) ptr; tmp << *val; } if (type != 'i'){ int *val = (int*) ptr; tmp << *val; } if (type != 's'){ string *val = (string*) ptr; tmp << *val; } if (type != 'v'){ VecDbl *val = (VecDbl*) ptr; tmp << "[ "; for (double v: *val) tmp << v << " "; tmp << " ]"; } } tmp << "\n"; return tmp.str(); } }; Vec var_reg; void GroupName(string name){ var_def add; add.name=name; var_reg.push_back(add); }; void RegVar(string name, bool *var){ var_def add; add.name=name; add.ptr=var; add.type='b'; var_reg.push_back(add); }; void RegVar(string name, double *var){ var_def add; add.name=name; add.ptr=var; add.type='d'; var_reg.push_back(add); }; void RegVar(string name, int *var){ var_def add; add.name=name; add.ptr=var; add.type='i'; var_reg.push_back(add); }; void RegVar(string name, string *var){ var_def add; add.name=name; add.ptr=var; add.type='s'; var_reg.push_back(add); }; void RegVar(string name, VecDbl *var){ var_def add; add.name=name; add.ptr=var; add.type='v'; var_reg.push_back(add); }; void GetVar(string name, bool &var, InputParser &in){ var = in.GetBool(name) ; }; void GetVar(string name, double &var, InputParser &in){ var = in.GetNumber(name); }; void GetVar(string name, int &var, InputParser &in){ var = in.GetNumber(name); }; void GetVar(string name, string &var, InputParser &in){ var = in.GetString(name); }; void GetVar(string name, VecDbl &var, InputParser &in){ var.clear(); in.GetVectorDouble(name,var); }; template void addVariable(string name, Tvar& var, InputParser &in){ GetVar(name,var,in); AddToDump(name,&var); }; // #define GETVARIABLE(var) addVariable( ##var, var, in); // END OF VARIABLE REGISTRATION void settings::readfromfile(const string fname){ //read input settings from file InputParser in(fname); sroot = in.GetNumber ( "sroot" ); ih1 = in.GetNumber ( "ih1" ); ih2 = in.GetNumber ( "ih2" ); nproc = in.GetNumber ( "nproc" ); kmuren = in.GetNumber ( "kmuren" ); kmufac = in.GetNumber ( "kmufac" ); kmures = in.GetNumber ( "kmures" ); fmuren = in.GetNumber ( "fmuren" ); fmufac = in.GetNumber ( "fmufac" ); fmures = in.GetNumber ( "fmures" ); - C1 = in.GetNumber ( "C1" ); - C3 = in.GetNumber ( "C3" ); kmuc = in.GetNumber ( "kmuc" ); kmub = in.GetNumber ( "kmub" ); kmut = in.GetNumber ( "kmut" ); g_param = in.GetNumber ( "g_param" ); flavour_kt = in.GetBool ( "flavour_kt" ); order = in.GetNumber ( "order" ); - zerowidth = in.GetBool ( "zerowidth" ); //false # zerowidth runningwidth = in.GetBool ( "runningwidth" ); rseed = in.GetNumber ( "rseed" ); blim = in.GetNumber ( "blim" ); LHAPDFset = in.GetString ( "LHAPDFset" ); LHAPDFmember = in.GetNumber ( "LHAPDFmember" ); ewscheme = in.GetNumber ( "ewscheme" ); Gf = in.GetNumber ( "Gf" ); zmass = in.GetNumber ( "zmass" ); wmass = in.GetNumber ( "wmass" ); xw = in.GetNumber ( "xw" ); aemmz = in.GetNumber ( "aemmz" ); zwidth = in.GetNumber ( "zwidth" ); wwidth = in.GetNumber ( "wwidth" ); Vud = in.GetNumber ( "Vud" ); Vus = in.GetNumber ( "Vus" ); Vub = in.GetNumber ( "Vub" ); Vcd = in.GetNumber ( "Vcd" ); Vcs = in.GetNumber ( "Vcs" ); Vcb = in.GetNumber ( "Vcb" ); Zuu = in.GetNumber ( "Zuu" ); Zdd = in.GetNumber ( "Zdd" ); Zcc = in.GetNumber ( "Zcc" ); Zss = in.GetNumber ( "Zss" ); Zbb = in.GetNumber ( "Zbb" ); damp = in.GetBool ( "damp" ); dampk = in.GetNumber ( "dampk" ); dampdelta = in.GetNumber ( "dampdelta" ); dampmode = in.GetNumber ( "dampmode" ); qtcutoff = in.GetNumber ( "qtcutoff" ); modlog = in.GetBool ( "modlog" ); xqtcut = in.GetNumber ( "xqtcut" ); qtcut = in.GetNumber ( "qtcut" ); intDimRes = in.GetNumber ( "intDimRes" ); intDimBorn = in.GetNumber ( "intDimBorn" ); intDimCT = in.GetNumber ( "intDimCT" ); - intDimVJ = in.GetNumber ( "intDimVJ" ); - fixedorder = in.GetBool ( "fixedorder" ); + intDimVJ = in.GetNumber ( "intDimVJ" ); + BORNquad = in.GetBool ( "BORNquad" ); + CTquad = in.GetBool ( "CTquad" ); + VJquad = in.GetBool ( "VJquad" ); + fixedorder = in.GetBool ( "fixedorder_only" ); doBORN = in.GetBool ( "doBORN" ); doCT = in.GetBool ( "doCT" ); doVJ = in.GetBool ( "doVJ" ); doVJREAL = in.GetBool ( "doVJREAL" ); doVJVIRT = in.GetBool ( "doVJVIRT" ); cubaverbosity = in.GetNumber ( "cubaverbosity" ); - cubacores = in.GetNumber ( "cubacores" ); + cubacores = in.GetNumber ( "cores" ); cubanbatch = in.GetNumber ( "cubanbatch" ); niterBORN = in.GetNumber ( "niterBORN" ); niterCT = in.GetNumber ( "niterCT" ); niterVJ = in.GetNumber ( "niterVJ" ); vegasncallsBORN = in.GetNumber ( "vegasncallsBORN" ); vegasncallsCT = in.GetNumber ( "vegasncallsCT" ); vegasncallsVJLO = in.GetNumber ( "vegasncallsVJLO" ); vegasncallsVJREAL = in.GetNumber ( "vegasncallsVJREAL" ); vegasncallsVJVIRT = in.GetNumber ( "vegasncallsVJVIRT" ); vegascollect = in.GetBool ( "vegascollect" ); pcubature = in.GetBool ( "pcubature" ); relaccuracy = in.GetNumber ( "relaccuracy" ); absaccuracy = in.GetNumber ( "absaccuracy" ); costhmin = in.GetNumber ( "costhmin" ); costhmax = in.GetNumber ( "costhmax" ); makecuts = in.GetBool ( "makecuts" ); lptcut = in.GetNumber ( "lptcut" ); lycut = in.GetNumber ( "lycut" ); mtcut = in.GetNumber ( "mtcut" ); etmisscut = in.GetNumber ( "etmisscut" ); lepptcut = in.GetNumber ( "lepptcut" ); lepycut = in.GetNumber ( "lepycut" ); alpptcut = in.GetNumber ( "alpptcut" ); alpycut = in.GetNumber ( "alpycut" ); lcptcut = in.GetNumber ( "lcptcut" ); lcymin = in.GetNumber ( "lcymin" ); lcymax = in.GetNumber ( "lcymax" ); lfptcut = in.GetNumber ( "lfptcut" ); lfymin = in.GetNumber ( "lfymin" ); lfymax = in.GetNumber ( "lfymax" ); cthCSmin = in.GetNumber ( "cthCSmin" ); cthCSmax = in.GetNumber ( "cthCSmax" ); cubaint = in.GetBool ( "cubaint" ); //true # integration with Cuba Suave trapezint = in.GetBool ( "trapezint" ); //false # trapezoidal rule for the phi_lep integration and semi-analytical for costh quadint = in.GetBool ( "quadint" ); //false # quadrature rule for the phi_lep integration and semi-analytical for costh suavepoints = in.GetNumber ( "suavepoints" ); //1000000 # number of points for suave integration, newpoints is set to suavepoints/10; nphitrape = in.GetNumber ( "nphitrape" ); //1000 # number of steps for trapezoidal rule of phi_lep integration phiintervals = in.GetNumber ( "phiintervals" ); phirule = in.GetNumber ( "phirule" ); ncstart = in.GetNumber ( "ncstart" ); //1000 # starting sampling for the costh semi-analytical integration (common settings for the trapezoidal and quadrature rules) qtrec_naive = in.GetBool ( "qtrec_naive" ); //false qtrec_cs = in.GetBool ( "qtrec_cs" ); //false qtrec_kt0 = in.GetBool ( "qtrec_kt0" ); //true timeprofile = in.GetBool ( "timeprofile" ); //false # debug and time profile resummation integration verbose = in.GetBool ( "verbose" ); //false # debug and time profile costh phi_lep integration gridverbose = in.GetBool ( "gridverbose" ); //false # debug and time profile costh phi_lep integration texttable = in.GetBool ( "texttable" ); // + redirect = in.GetBool ( "redirect" ); // unicode = in.GetBool ( "unicode" ); // - resumcpp = in.GetBool ( "resumcpp" ); - ctcpp = in.GetBool ( "ctcpp" ); + silent = in.GetBool ( "silent" ); // + makehistos = in.GetBool ( "makehistos" ); // useGamma = in.GetBool ( "useGamma" );// PDFerrors = in.GetBool ( "PDFerrors" );// opts_.approxpdf_ = in.GetNumber ( "opts_approxpdf" ); //0 opts_.pdfintervals_ = in.GetNumber ( "opts_pdfintervals" ); //100 pdfrule = in.GetNumber ( "pdfrule" ); evolmode = in.GetNumber ("evolmode"); - vfnsudakov = in.GetBool ("vfnsudakov"); bprescription = in.GetNumber ("bprescription"); bintaccuracy = in.GetNumber ( "bintaccuracy" ); phibr = in.GetNumber ( "phibr" ); bcf = in.GetNumber ( "bcf" ); mellininv = in.GetNumber ( "mellininv" ); mellinintervals = in.GetNumber ( "mellinintervals" ); mellinrule = in.GetNumber ( "mellinrule" ); zmax = in.GetNumber ( "zmax" ); cpoint = in.GetNumber ( "cpoint" ); phi = in.GetNumber ( "phi" ); mellincores = in.GetNumber ( "mellincores" ); mellin1d = in.GetBool ( "mellin1d" ); xspace = in.GetBool ( "xspace" ); yintervals = in.GetNumber ( "yintervals" ); yrule = in.GetNumber ( "yrule" ); qtintervals = in.GetNumber ( "qtintervals" ); qtrule = in.GetNumber ( "qtrule" ); abintervals = in.GetNumber ( "abintervals" ); abrule = in.GetNumber ( "abrule" ); vjphirule = in.GetNumber ( "vjphirule" ); zrule = in.GetNumber ( "zrule" ); xrule = in.GetNumber ( "xrule" ); ptbinwidth = in.GetBool ( "ptbinwidth" ); ybinwidth = in.GetBool ( "ybinwidth" ); force_binsampling = in.GetBool ( "force_binsampling" ); helicity = in.GetNumber ( "helicity" ); output_filename = in.GetString ( "output_filename" ); return ; } void settings::check_consitency(){ // additional conditions if (order != 0 && order != 1 && order != 2) throw invalid_argument("Invalid order, please select 0 (LO) 1 (NLO) or 2 (NNLO)"); if (nproc != 1 && nproc != 2 && nproc != 3) throw invalid_argument("Wrong process, please select nproc = 1 (W+), 2 (W-), or 3(Z)"); if (order == 0) { doCT = false; doVJ = false; } if (order != 2) { doVJREAL = false; doVJVIRT = false; } //In fixed order mode, a_param must be one if (fixedorder == true) { - cout << "Asked for fixed order predictions, enforce kmures = 1.0" << endl; + //cout << "Asked for fixed order only predictions, enforce kmures = 1.0" << endl; kmures = 1.0; + fmures = 1; } if (evolmode > 4 || evolmode < 0) { cout << "wrong value for evolmode: available evolmodes: 0,1,2,3,4" << endl; exit (-1); } //if (fmufac > 0 && evolmode < 3 && order > 0 && fixedorder == false) // { // //cannot use a dynamic muren, mufac, when the PDFs are converted from x-space to N-space at the factorisation scale // cout << "At NLL and NNLL mufac = mll is possible only with evolmode = 3 or 4" << endl; // exit (-1); // } + //minimal b prescription in the complex plain available only for evolmode 0 + //real axix minimal presxription works only at LL + + //with modlog = false can run only the resummation term + if (PDFerrors == true && LHAPDFmember != 0) { cout << "Asked for PDFerrors, enforce LHAPDFmember = 0" << endl; LHAPDFmember = 0; } if (qtcut <= 0 && xqtcut <= 0) { cout << "At least one between qtcut and xqtcut must be > 0" << endl; exit (-1); } + //Automatic selector of integration type + //check if yrange is above ymax + if (intDimBorn < 0) + if (BORNquad) + { + intDimBorn = 2; + if (opts.makecuts) + intDimRes = 2; + else + intDimRes = 1; // -> Check this works also when not fully integrated in rapidity!!! + } + else + { + intDimBorn = 4; + intDimRes = 4; + } + + if (intDimCT < 0) + if (CTquad) + if (opts.makecuts) // || yrange below ymax + intDimCT = 2; + else + intDimCT = 1; + else + intDimCT = 8; + + if (intDimVJ < 0) + if (VJquad) + if (opts.makecuts) + intDimVJ = 5; + else + intDimVJ = 3; + else + intDimVJ = 7; + + if (intDimVJ < 7 && order == 2) + { + cout << "cannot perform quadrature integration for V+jet at NNLO" << endl; + exit (-1); + } + // resummation term integration dimension if (intDimRes<4 && intDimRes>0){ resint1d = (intDimRes == 1); resint2d = (intDimRes == 2); resint3d = (intDimRes == 3); resintvegas = false; } else { resint2d = false; resint3d = false; resintvegas = true; } // born term integration dimension if (intDimBorn < 4 && intDimBorn>1){ bornint2d = (intDimBorn == 2); bornintvegas4d = false; bornintvegas6d = false; } else { bornint2d = false; bornintvegas4d = (intDimBorn == 4); bornintvegas6d = (intDimBorn > 5); } // counter term integration dimension if (intDimCT<4 && intDimCT>0){ ctint1d = (intDimCT == 1); ctint2d = (intDimCT == 2); ctint3d = (intDimCT == 3); ctintvegas6d = false; ctintvegas8d = false; } else { ctint2d = false; ctint3d = false; ctintvegas6d = (intDimCT <= 6); ctintvegas8d = (intDimCT > 6); } // V+J integration dimension if (intDimVJ < 7 && intDimVJ > 2) { vjint3d = (intDimVJ == 3); vjint5d = (intDimVJ == 5); vjintvegas7d = false; } else { vjint3d = false; vjint5d = false; vjintvegas7d = true; } if (mellin1d && (!(resint2d || resint1d) || makecuts)) { cout << "mellin1d option is possible only for 1d or 2d integration of resummed piece, no cuts on leptons, and integration between [-ymin,ymax]" << endl; exit (-1); } if (mellinintervals*mellinrule >= 512) { cout << "mellinintervals*mellinrule should be less than 512 " << endl; exit(-1); } if (makecuts && vjint3d) { cout << "Required cuts on the final state leptons, enforce 5D integration for V+J fixed order cross section" << endl; vjint3d = false; vjint5d = true; } if (makecuts && helicity >= 0) { cout << "Required cuts on the final state leptons, cannot calculate helicity cross sections, enforce helicity = -1" << endl; helicity = -1; } if (opts_.approxpdf_ == 1) { cout << "DYRES-style approximate PDF requested, enforce vegas integration for the resummed cross section" << endl; resint2d = false; resint3d = false; resintvegas = true; } // -- binning // check bins size if ( bins.qtbins .size() < 2) throw QuitProgram("Option `qtbins` needs at least 2 items "); if ( bins.ybins .size() < 2) throw QuitProgram("Option `ybins` needs at least 2 items "); if ( bins.mbins .size() < 2) throw QuitProgram("Option `mbins` needs at least 2 items "); // check sorting sort( bins.qtbins .begin () , bins.qtbins .end () ) ; sort( bins.ybins .begin () , bins.ybins .end () ) ; sort( bins.mbins .begin () , bins.mbins .end () ) ; // set histogram bins bins.hist_qt_bins = bins.qtbins ; bins.hist_y_bins = bins.ybins ; bins.hist_m_bins = bins.mbins ; // integration boundaries phasespace::setbounds( bins. mbins .front() , bins. mbins .back() , bins. qtbins .front() , bins. qtbins .back() , bins. ybins .front() , bins. ybins .back() ); return ; } void settings::dumpAll(){ printf("==Listing settings==\n"); bool print_inputs = true; - bool print_inputsDYRES = true; + bool print_process_inputs = true; bool print_masses = true; - if (print_inputsDYRES) { - printf("Input DYRES settings:\n"); + if (print_process_inputs) { + printf("Input process settings:\n"); dumpD ( "sroot ", energy_ . sroot_ ) ; dumpI ( "ih1 ", density_ . ih1_ ) ; dumpI ( "ih2 ", density_ . ih2_ ) ; dumpI ( "nproc ", nproc_ . nproc_ ) ; - // dumpD ( "a_param ", a_param_ . a_param_ ) ; - dumpD ( "g_param ", g_param_ . g_param_ ) ; - dumpI ( "order ", nnlo_ . order_ ) ; - dumpB ( "zerowidth ", zerowidth_ . zerowidth_ ) ; } if (print_inputs) { printf("Input settings:\n"); + dumpD ( "g_param ", g_param_ . g_param_ ) ; + dumpI ( "order ", nnlo_ . order_ ) ; dumpD ( "kmuren ", kmuren ) ; dumpD ( "kmufac ", kmufac ) ; dumpD ( "kmures ", kmures ) ; dumpI ( "fmuren ", kmuren ) ; dumpI ( "fmufac ", kmufac ) ; dumpI ( "fmures ", kmures ) ; - dumpD ( "C1 ", C1 ) ; - dumpD ( "C3 ", C3 ) ; dumpD ( "kmuc ", kmuc ) ; dumpD ( "kmub ", kmub ) ; dumpD ( "kmut ", kmut ) ; dumpB ( "flavour_kt", flavour_kt ); dumpD( "blim ", blim ) ; dumpS("LHAPDFset ", LHAPDFset ); dumpI("LHAPDFmember ", LHAPDFmember ); dumpI("rseed ", rseed ); dumpI("ewscheme ", ewscheme ); dumpD("Gf" , Gf); dumpD("zmass" , zmass); dumpD("wmass" , wmass ); dumpD("xw" , xw); dumpD("aemmz" , aemmz); dumpD("zwidth" , zwidth); dumpD("wwidth" , wwidth); dumpB("runningwidth" , runningwidth); dumpD( "Vud", Vud); dumpD( "Vus", Vus); dumpD( "Vub", Vub); dumpD( "Vcd", Vcd); dumpD( "Vcs", Vcs); dumpD( "Vcb", Vcb); dumpD( "Zuu", Zuu); dumpD( "Zdd", Zdd); dumpD( "Zss", Zss); dumpD( "Zcc", Zcc); dumpD( "Zbb", Zbb); //dumpD("ylow ", ylow ); //dumpD("yhigh ", yhigh ); //dumpD("mlow ", mlow ); //dumpD("mhigh ", mhigh ); dumpB("damp", damp ); dumpD("dampk", dampk ); dumpD("dampdelta", dampdelta ); dumpI("dampmode", dampmode ); dumpD("qtcutoff", qtcutoff ); dumpB("modlog", modlog ); dumpD("xqtcut", xqtcut ); dumpD("qtcut", qtcut ); dumpB("useGamma ", useGamma ); dumpI("intDimRes ", intDimRes ); dumpB("resint2d ", resint2d ); dumpB("resint3d ", resint3d ); dumpB("resintvegas ", resintvegas ); dumpI("intDimBorn ", intDimBorn ); dumpB("bornint2d ", bornint2d ); dumpB("bornintvegas4d ", bornintvegas4d ); dumpB("bornintvegas6d ", bornintvegas6d ); dumpI("intDimCT ", intDimCT ); dumpB("ctint2d ", ctint2d ); dumpB("ctint3d ", ctint3d ); dumpB("ctintvegas6d ", ctintvegas6d ); dumpB("ctintvegas8d ", ctintvegas8d ); dumpI("intDimVJ ", intDimVJ ); dumpB("vjint3d ", vjint3d ); dumpB("vjint5d ", vjint5d ); dumpB("vjintvegas7d ", vjintvegas7d ); - dumpB("fixedorder ", fixedorder ); + dumpB("fixedorder_only ", fixedorder ); + dumpB("BORNquad ", BORNquad ); + dumpB("CTquad ", CTquad ); + dumpB("VJquad ", VJquad ); dumpB("doBORN ", doBORN ); dumpB("doCT ", doCT ); dumpB("doVJ ", doVJ ); dumpB("doVJREAL ", doVJREAL ); dumpB("doVJVIRT ", doVJVIRT ); dumpI("cubaverbosity ", cubaverbosity ); - dumpI("cubacores ", cubacores ); + dumpI("cores ", cubacores ); dumpI("cubanbatch ", cubanbatch ); dumpI("niterBORN ", niterBORN ); dumpI("niterCT ", niterCT ); dumpI("niterVJ ", niterVJ ); dumpD("vegasncallsBORN ", vegasncallsBORN ); dumpD("vegasncallsCT ", vegasncallsCT ); dumpD("vegasncallsVJLO ", vegasncallsVJLO ); dumpD("vegasncallsVJREAL ", vegasncallsVJREAL ); dumpD("vegasncallsVJVIRT ", vegasncallsVJVIRT ); dumpB("vegascollect ", vegascollect ); dumpB("pcubature ", pcubature ); dumpD("relaccuracy ", relaccuracy ); dumpD("absaccuracy ", absaccuracy ); dumpD("costhmin ", costhmin ); dumpD("costhmax ", costhmax ); dumpB("makecuts ", makecuts ); dumpD("lptcut ", lptcut ); dumpD("lycut ", lycut ); dumpD("mtcut ", mtcut ); dumpD("cthCSmin ", cthCSmin ); dumpD("cthCSmax ", cthCSmax ); dumpD("etmisscut ", etmisscut ); dumpB("cubaint ", cubaint ); dumpB("trapezint ", trapezint ); dumpB("quadint ", quadint ); dumpI("suavepoints ", suavepoints ); dumpI("nphitrape ", nphitrape ); dumpI("phiintervals ", phiintervals ); dumpI("phirule ", phirule ); dumpI("ncstart ", ncstart ); dumpB("qtrec_naive ", qtrec_naive ); dumpB("qtrec_cs ", qtrec_cs ); dumpB("qtrec_kt0 ", qtrec_kt0 ); dumpB("timeprofile ", timeprofile ); dumpB("verbose ", verbose ); dumpB("gridverbose ", gridverbose ); + dumpB("unicode ", unicode ); + dumpB("silent ", silent ); + dumpB("makehistos ", makehistos ); dumpB("texttable ", texttable ); dumpB("resumcpp ", resumcpp ); dumpB("ctcpp ", ctcpp ); dumpI("approxpdf ", opts_.approxpdf_ ); dumpI("pdfintervals ", opts_.pdfintervals_ ); dumpI("evolmode ", evolmode ); - dumpB("vfnsudakov ", vfnsudakov ); dumpI("bprescription ", bprescription ); dumpB("phibr ", phibr ); dumpB("bcf ", bcf ); dumpB("PDFerrors ", PDFerrors ); dumpI("mellininv ", mellininv ); dumpI("mellinintervals ", mellinintervals ); dumpI("mellinrule ", mellinrule ); dumpD("zmax ", zmax ); dumpD("cpoint ", cpoint ); dumpD("phi ", phi ); dumpD("mellincores ", mellincores ); dumpB("mellin1d ", mellin1d ); dumpB("xspace ", xspace ); dumpI("yintervals ", yintervals ); dumpI("yrule ", yrule ); dumpI("qtintervals ", qtintervals ); dumpI("qtrule ", qtrule ); dumpI("abintervals ", abintervals ); dumpI("abrule ", abrule ); dumpI("vjphirule ", vjphirule ); dumpI("zrule ", zrule ); dumpI("xrule ", xrule ); dumpB("ptbinwidth ", ptbinwidth ); dumpB("ybinwidth ", ybinwidth ); + dumpB("mbinwidth ", mbinwidth ); dumpB("force_binsampling ", force_binsampling ); dumpI("helicity ", helicity ); dumpS("output_filename ", output_filename ); } if (print_masses){ printf("Masses and EW constants:\n"); dumpD ( "md " , dymasses_ . md_ ); dumpD ( "mu " , dymasses_ . mu_ ); dumpD ( "ms " , dymasses_ . ms_ ); dumpD ( "mc " , dymasses_ . mc_ ); dumpD ( "mb " , dymasses_ . mb_ ); dumpD ( "mt " , dymasses_ . mt_ ); dumpD ( "mel " , dymasses_ . mel_ ); dumpD ( "mmu " , dymasses_ . mmu_ ); dumpD ( "mtau " , dymasses_ . mtau_ ); dumpD ( "hmass " , dymasses_ . hmass_ ); dumpD ( "hwidth " , dymasses_ . hwidth_ ); dumpD ( "wmass " , dymasses_ . wmass_ ); dumpD ( "wwidth " , dymasses_ . wwidth_ ); dumpD ( "zmass " , dymasses_ . zmass_ ); dumpD ( "zwidth " , dymasses_ . zwidth_ ); dumpD ( "twidth " , dymasses_ . twidth_ ); dumpD ( "mtausq " , dymasses_ . mtausq_ ); dumpD ( "mcsq " , dymasses_ . mcsq_ ); dumpD ( "mbsq " , dymasses_ . mbsq_ ); /* dumpD ( "Gf_inp " , ewinput_ . Gf_inp_ ); dumpD ( "aemmz_inp " , ewinput_ . aemmz_inp_ ); dumpD ( "xw_inp " , ewinput_ . xw_inp_ ); dumpD ( "wmass_inp " , ewinput_ . wmass_inp_ ); dumpD ( "zmass_inp " , ewinput_ . zmass_inp_ ); */ dumpD ( "Vud " , cabib_ . Vud_ ); dumpD ( "Vus " , cabib_ . Vus_ ); dumpD ( "Vub " , cabib_ . Vub_ ); dumpD ( "Vcd " , cabib_ . Vcd_ ); dumpD ( "Vcs " , cabib_ . Vcs_ ); dumpD ( "Vcb " , cabib_ . Vcb_ ); dumpD ( "epinv " , epinv_ . epinv_ ); dumpD ( "epinv2 " , epinv2_ . epinv2_ ); } printf("end of setting dump.\n\n"); } void settings::dumpI( string var,int val){ printf( " %s = %d\n", var.c_str(), val); } void settings::dumpD( string var,double val){ printf( " %s = %f\n", var.c_str(), val); } void settings::dumpS( string var,string val){ printf( " %s = %s\n", var.c_str(), val.c_str()); } void settings::dumpB( string var,bool val){ printf( " %s = %s\n", var.c_str(), val ? "true" : "false" ); } vector settings::Tokenize(string val,char Delim){ vector vec; size_t pos = 0; string tmp; while (!val.empty()){ // find delim pos = val.find_first_of(Delim); if (pos==string::npos){ // last item tmp = val; val.clear(); } else { // get substring tmp = val.substr(0,pos); val = val.substr(pos+1); } // add to vector if (!tmp.empty()) vec.push_back(tmp); } return vec; } bool settings::IsNumber(const string &s) { double dummy; try { dummy = stod(s); return true; } catch (const std::exception &e){ return false; } } void settings::parse_binning(string name, vector &bins, po::Options &args){ if (args.count(name)) { string e("Unsupported value of "+name+" : need 3 numbers seperated by comma: 'N,lo,hi' "); string val=args[name.c_str()].as(); ToLower(val); vector vec = Tokenize(val); // check value if (vec.size()!=3) throw QuitProgram(e+" not 3 numbers."); for (auto s : vec) if (!IsNumber(s)) throw QuitProgram(e+" not numbers."); // retrieve N,lo,hi int N = stod(vec[0]); double lo = stod(vec[1]); double hi = stod(vec[2]); if (lo>hi) throw QuitProgram(e+" lo is more then hi."); if (N<1) throw QuitProgram(e+" N is not at least 1."); // make binning bins.clear(); //loop with double has problems for equality test (try --ybins 25,0,5) //for (double loedge=lo; loedge<=hi; loedge+=(hi-lo)/double(N)) bins.push_back(loedge); for (int i=0; i <= N; i++) bins.push_back(lo+i*(hi-lo)/double(N)); } } void binning::GetBins(string name, vector &vec){ vec.clear(); // CLI defined if (name == "qt" && qtbins .size()!=0) { vec = qtbins; return; } if (name == "y" && ybins .size()!=0) { vec = ybins; return; } if (name == "m" && mbins .size()!=0) { vec = mbins; return; } // input file defined name+="_bins"; in.GetVectorDouble(name.c_str(), vec); if ( vec.size() < 2) throw QuitProgram( "Option `" +name+ "` needs at least 2 items "); } void binning::readfromfile(const string fname){ in.parse_file(fname); in.GetVectorDouble("qt_bins" , qtbins ); in.GetVectorDouble("y_bins" , ybins ); in.GetVectorDouble("m_bins" , mbins ); hist_qt_bins .clear(); hist_y_bins .clear(); hist_m_bins .clear(); return; } // InputParser definitions // InputParser::InputParser( string _filename, string _charset, string _white): filename ( _filename ), Ccommnt ( _charset[0] ), Cassign ( _charset[1] ), CopenAr ( _charset[2] ), CdeliAr ( _charset[3] ), CclosAr ( _charset[4] ), Swhite ( _white ) { // parse default try { parse_file((string)SHAREDIR+"/default.in"); } catch (invalid_argument &e1){ try { parse_file("default.in"); } catch (invalid_argument &e2){ throw invalid_argument( string( "Can not load default settings:\n") + string(e1.what()) + string("\n") + string(e2.what()) + string("\n") ); } } // parse custom settings if (filename.compare("")!=0) parse_file(filename); } InputParser::~InputParser(){ } double InputParser::GetNumber(string name){ has_key(name); string val = data[name]; try { return stod(val); } catch (const std::exception &e){ printf("Cannot read option '%s' with value '%s' as number.\n",name.c_str(), val.c_str() ); throw e; } } string InputParser::GetString(string name){ has_key(name); string val = data[name]; trim(val); return val; } bool InputParser::GetBool(string name){ has_key(name); string val = data[name]; // lower case std::transform(val.begin(), val.end(), val.begin(), ::tolower); bool result = (val.compare(0,4,"true") == 0); //printf(" InputParser::GetBool processing key `%s` with value `%s` as result `%d`\n", name.c_str(), val.c_str(), result); return result; } void InputParser::GetVectorDouble(string name, vector &vec){ has_key(name); + vec.clear(); string val = data[name]; // has open/close array size_t strBegin = val.find(CopenAr,0); size_t strEnd = val.find(CclosAr,0); // we need both open and close otherwise is something wrong if (strBegin==string::npos || strEnd==string::npos) throw invalid_argument("Missing open/close character."); // parse what is between them val = val.substr(strBegin+1,strEnd-strBegin-1); size_t pos = 0; string tmp; while (!val.empty()){ // find delim pos = val.find(CdeliAr); if (pos==string::npos){ // last item tmp = val; val.clear(); } else { // get substring tmp = val.substr(0,pos); val = val.substr(pos+1); } // get substring trim(tmp); // expecting number otherwise exception if (!tmp.empty()) vec.push_back(stod(tmp)); } return; } void InputParser::parse_file(const string fname){ ifstream fstrm(fname.c_str()); if ( ! fstrm.good() ) throw invalid_argument( string("Uknown file name ") + fname ); string line; // line by line while(getline(fstrm,line)) { size_t pos = 0; // check for comments pos = line.find(Ccommnt,pos); if (pos != string::npos) line = line.substr(0,pos); // split string by delim pos = line.find(Cassign,0); if (pos == string::npos || line.empty()) continue; string key = line.substr(0,pos); string val = line.substr(pos+1); // remove leading / trailing whitespace trim(key); trim(val); /// @todo: Multiline setting. If has CopenAr load until CclosAr // save to map data[key]=val; } fstrm.close(); return; } void InputParser::trim(string & str){ size_t strBegin = str.find_first_not_of(Swhite); if (strBegin == std::string::npos){ str=""; return ; // no content } size_t strEnd = str.find_last_not_of(Swhite); size_t strRange = strEnd - strBegin + 1; str = str.substr(strBegin, strRange); return; } void InputParser::has_key(const string key){ if ( data.count(key) == 0 ){ string msg = "Missing setting with name '"; msg += key; msg += "'"; throw invalid_argument(msg.c_str()); } return; } diff --git a/src/settings.h b/src/settings.h index dea18a3..8437b9f 100644 --- a/src/settings.h +++ b/src/settings.h @@ -1,329 +1,328 @@ #ifndef settings_h #define settings_h #include using namespace std; #include #include #include #include class InputParser { public: // constructor InputParser( string _filename = "", string _charset="#=[ ]", string _white=" \t"); ~InputParser(); // getters double GetNumber(string name); string GetString(string name); bool GetBool(string name); void GetVectorDouble(string name, vector &vec); void parse_file(const string fname); private : // functions void trim(string & str); void has_key(const string key); // data members map data; ///< Data table. string filename; ///< Input file. // parser characters char Ccommnt; char Cassign; char CopenAr; char CclosAr; char CdeliAr; string Swhite; }; // Simple program quiting exception struct QuitProgram : public std::runtime_error { QuitProgram(string msg) : std::runtime_error (msg) {}; }; // Forward declaration namespace cxxopts{ class Options; } namespace po=cxxopts; // inspired by po = boost::program_options class settings { public: settings() {}; void parse_options(int argc, char * argv[]); void readfromfile(const string fname); void check_consitency(); void parse_binning(string name, vector &vec, po::Options &args); // private: void dumpAll(); void dumpI(string var, int val ); void dumpD(string var, double val ); void dumpS(string var, string val ); void dumpB(string var, bool val ); // string helpers void ToLower(string &val){std::transform(val.begin(), val.end(), val.begin(), ::tolower);} void ToUpper(string &val){std::transform(val.begin(), val.end(), val.begin(), ::toupper);} vector Tokenize(string val, char Delim=','); // is number: http://stackoverflow.com/a/16575025 bool IsNumber(const string &s); //process settings double sroot; int ih1; int ih2; int nproc; double g_param; bool flavour_kt; int order; //PDF settings string LHAPDFset ; int LHAPDFmember ; - + bool externalpdf; + //functional forms of the QCD scales int fmures; int fmuren; int fmufac; //scale factors for the QCD scales double kmures; double kmuren; double kmufac; //scale factors for the matching scales double kmuc; double kmub; double kmut; - //Additional resummation scales - double C1,C3; - // double a_param; //EW parameters int ewscheme; double Gf, zmass, wmass; double xw, aemmz; double zwidth, wwidth; - bool zerowidth; //Fixed width to running width translation bool runningwidth; //CKM matrix double Vud, Vus, Vub; double Vcd, Vcs, Vcb; //Z/gamma* coupling double Zuu, Zdd, Zss, Zcc, Zbb; //resonance mass and width (used for breit wigner unweighting) double rmass, rwidth; // photon switch bool useGamma; //integration boundaries //double ylow; //double yhigh; //double mlow; //double mhigh; //Resummation damping bool damp; double dampk, dampdelta; int dampmode; //Resummation cutoff double qtcutoff; //Modified logarithms bool modlog; //qtcut double xqtcut, qtcut; //integration settings int rseed; //dimension of integration for the resummed part int intDimRes; bool resint1d, resint2d, resint3d, resintvegas; //dimension of integration for the born configuration int intDimBorn; bool bornint2d, bornintvegas4d, bornintvegas6d; //type of integration for the counterterm int intDimCT; bool ctint1d, ctint2d, ctint3d, ctintvegas6d, ctintvegas8d; - // //type of integration for the V+j at LO + //type of integration for the V+j at LO int intDimVJ; bool vjint3d, vjint5d, vjintvegas7d; + + //type of integration, automatic selector + bool BORNquad, CTquad, VJquad; //term switches bool doBORN; bool doCT; bool doVJ; bool doVJREAL, doVJVIRT; //resummation or fixed order switch bool fixedorder; //Cuba settings int cubaverbosity; int cubacores; int cubanbatch; int niterBORN; int niterCT; int niterVJ; int vegasncallsBORN ; int vegasncallsCT ; int vegasncallsVJLO ; long long int vegasncallsVJREAL ; int vegasncallsVJVIRT ; bool vegascollect; //cubature settings bool pcubature; double relaccuracy; double absaccuracy; //costh boundaries double costhmin, costhmax; //lepton fiducial cuts bool makecuts; double lptcut, lycut; //charged leptons double mtcut, etmisscut; double lepptcut, lepycut, alpptcut, alpycut; //lepton and antilepton double lcptcut, lcymin, lcymax, lfptcut, lfymin, lfymax; //lc and lf are absolute-rapidity-ordered leptons double cthCSmin, cthCSmax; //integration types and settings for costh phi_lep phase space bool cubaint; int suavepoints; bool trapezint; int nphitrape; int ncstart; //quadrature rule in phi_lep bool quadint; int phiintervals; int phirule; //settings for Bessel integration double bintaccuracy; //b-space prescription int bprescription; //blim parameter of the bstar prescription (acts as an IR cut-off) double blim; //arg(z) in the complex plane for the minimal prescription double phibr; //select the point bc, where the integration contour is bended in the complex plane, as a fraction of b_L = ... (Landau singularity) double bcf; //settings for Mellin integration int mellininv; int mellinintervals; int mellinrule; double zmax; double cpoint; double phi; int mellincores; bool mellin1d; bool xspace; //settings for x-to-N Mellin transform int pdfrule; //settings for rapidity integration in 2D resummed piece int yintervals; int yrule; //settings for qt integration in 2D counter term int qtintervals; int qtrule; //settings for alfa beta scaled-PDF integration in counter term and born fixed order int abintervals; int abrule; //settings for the phi integration in the V+J 5d LO term when makecuts is false int vjphirule; //settings for the z1, z2 integration in the V+J 3d NLO singular term int zrule; //settings for the x integration in the V+J 3d delta term int xrule; //qt-recoil prescriptions bool qtrec_naive, qtrec_cs, qtrec_kt0; // PDF errors bool PDFerrors; int totpdf; //debug settings bool timeprofile; bool verbose; bool gridverbose; - bool texttable; + //output settings + bool texttable; + bool redirect; bool unicode; + bool silent; + bool makehistos; + string output_filename; // Output Filenames //resummed code in C++ - bool resumcpp; + bool resumcpp = true; //use C++ code for resummation //counter term code in C++ - bool ctcpp; + bool ctcpp = true; //use C++ code for the counter term //dyres or pegasus PDF evolution int evolmode; - //VFN settings - bool vfnsudakov; - //bin width normalisation - bool ptbinwidth, ybinwidth; + bool ptbinwidth, ybinwidth, mbinwidth; // Force to loop over all bins even you have all Vegas integrands bool force_binsampling = false; // Calculate helicity cross sections int helicity; - - // Output Filenames - std::string output_filename; }; class binning { public: binning() {}; void readfromfile(const string fname); void GetBins(string name,vector &bins); // private: vector qtbins; vector ybins; vector mbins; vector hist_qt_bins; vector hist_y_bins; vector hist_m_bins; private: InputParser in; }; extern settings opts; extern binning bins; #endif diff --git a/vjet/vjint.C b/vjet/vjint.C index 89a2dd4..fef125f 100644 --- a/vjet/vjint.C +++ b/vjet/vjint.C @@ -1,443 +1,449 @@ #include "vjint.h" #include "settings.h" #include "interface.h" #include "resconst.h" #include "cubature.h" #include "gaussrules.h" #include "mesq.h" #include "coupling.h" #include "scales.h" #include "phasespace.h" #include "luminosity.h" #include "LHAPDF/LHAPDF.h" #include #include const double vjint::zmin = 1e-13;//1e-8; const double vjint::zmax = 1.;//1.-1e-10;//1.-1e-8; const double vjint::lz = log(zmax/zmin); int vjint::z1rule; int vjint::z2rule; double *vjint::t1; double *vjint::t2; double vjint::brz; double vjint::brw; +void vjint::release() +{ + delete[] t1; + delete[] t2; +} + void vjint::init() { z1rule = opts.zrule; z2rule = opts.zrule; t1 = new double [z1rule]; t2 = new double [z2rule]; double az = 0.; double bz = 1.; double cz = 0.5*(az+bz); double mz = 0.5*(bz-az); for (int j = 0; j < z1rule; j++) t1[j] = zmin*pow(zmax/zmin, cz+mz*gr::xxx[z1rule-1][j]); for (int j = 0; j < z2rule; j++) t2[j] = zmin*pow(zmax/zmin, cz+mz*gr::xxx[z2rule-1][j]); //gevpb_.gevpb_ = 3.8937966e8; //MCFM 6.8 value //gevpb_.gevpb_ = 0.389379e9; //dyres value //gevpb_.gevpb_ = gevfb/1000.; // flagch_.flagch_ = 0; // vegint_.iter_ = 20; // vegint_.locall_ = 10000; // vegint_.nlocall_ = 20000; // dypara_.ss_ = opts.sroot; // dypara_.s_ = pow(dypara_.ss_,2); // dypdf_.ih1_ = opts.ih1; // dypdf_.ih2_ = opts.ih2; //vjorder_.iord_ = opts.order - 1; // if (opts.nproc == 3) // { // if (opts.useGamma && !opts.zerowidth) // prodflag_.prodflag_ = 5; // else // prodflag_.prodflag_ = 3; // } // else if (opts.nproc == 1) // prodflag_.prodflag_ = 21; // else if (opts.nproc == 2) // prodflag_.prodflag_ = 22; ckm_.vud_ = cabib_.Vud_; ckm_.vus_ = cabib_.Vus_; ckm_.vub_ = cabib_.Vub_; ckm_.vcd_ = cabib_.Vcd_; ckm_.vcs_ = cabib_.Vcs_; ckm_.vcb_ = cabib_.Vcb_; ckm_.vtd_ = 0.; ckm_.vts_ = 0.; ckm_.vtb_ = 0.; double cw2 = 1.- coupling::xw; // em_.aemmz_ = coupling::aemmz; //sqrt(2.)* ewcouple_.Gf_ *pow(coupling::wmass,2)* ewcouple_.xw_ /M_PI; brz = 1./dymasses_.zwidth_*coupling::aemmz/24.*coupling::zmass *(pow(-1.+2.*coupling::xw,2)+pow(2.*coupling::xw,2))/(coupling::xw*cw2); //=0.033638 brw = 1./dymasses_.wwidth_*coupling::aemmz*coupling::wmass/(12.*coupling::xw); //=0.10906 //quarks are ordered according to mass: //1,2,3,4,5,6 //u,d,s,c,b,t //double equ = 2./3.; //up-quarks electric charge //double eqd = -1./3.; //down-quarks electric charge //quarks_.eq_[0]=equ; //quarks_.eq_[1]=eqd; //quarks_.eq_[2]=eqd; //quarks_.eq_[3]=equ; //quarks_.eq_[4]=eqd; quarks_.eq_[0] = ewcharge_.Q_[MAXNF+2]; quarks_.eq_[1] = ewcharge_.Q_[MAXNF+1]; quarks_.eq_[2] = ewcharge_.Q_[MAXNF+3]; quarks_.eq_[3] = ewcharge_.Q_[MAXNF+4]; quarks_.eq_[4] = ewcharge_.Q_[MAXNF+5]; //definition of 'generalized' ckm matrix: // (uu ud us uc ub ut) // (du dd ds dc db dt) //ckm=(su sd ss sc sb st) // (cu cd cs cc cb ct) // (bu bd bs bc bb bt) // (tu td ts tc tb tt) for (int i = 0; i < 6; i++) for (int j = 0; j < 6; j++) quarks_.ckm_[j][i] = 0.; quarks_.ckm_[1][0]=ckm_.vud_; quarks_.ckm_[2][0]=ckm_.vus_; quarks_.ckm_[4][0]=ckm_.vub_; quarks_.ckm_[0][1]=ckm_.vud_; quarks_.ckm_[3][1]=ckm_.vcd_; quarks_.ckm_[5][1]=ckm_.vtd_; quarks_.ckm_[0][2]=ckm_.vus_; quarks_.ckm_[3][2]=ckm_.vcs_; quarks_.ckm_[5][2]=ckm_.vts_; quarks_.ckm_[1][3]=ckm_.vcd_; quarks_.ckm_[2][3]=ckm_.vcs_; quarks_.ckm_[4][3]=ckm_.vcb_; quarks_.ckm_[0][4]=ckm_.vub_; quarks_.ckm_[3][4]=ckm_.vcb_; quarks_.ckm_[5][4]=ckm_.vtb_; quarks_.ckm_[1][5]=ckm_.vtd_; quarks_.ckm_[2][5]=ckm_.vts_; quarks_.ckm_[4][5]=ckm_.vtb_; //definition of 'delta' matrix for (int i = 0; i < MAXNF; i++) for (int j = 0; j < MAXNF; j++) quarks_.delta_[j][i] = 0.; for (int i = 0; i < MAXNF; i++) quarks_.delta_[i][i] = 1.; //definition of tau3's Pauli matrix for (int i = 0; i < MAXNF; i++) for (int j = 0; j < MAXNF; j++) quarks_.tau3_[j][i] = 0.; //quarks_.tau3_[0][0]=1.; //quarks_.tau3_[1][1]=-1.; //quarks_.tau3_[2][2]=-1.; //quarks_.tau3_[3][3]=1.; //quarks_.tau3_[4][4]=-1.; quarks_.tau3_[0][0] = ewcharge_.tau_[MAXNF+2]; quarks_.tau3_[1][1] = ewcharge_.tau_[MAXNF+1]; quarks_.tau3_[2][2] = ewcharge_.tau_[MAXNF+3]; quarks_.tau3_[3][3] = ewcharge_.tau_[MAXNF+4]; quarks_.tau3_[4][4] = ewcharge_.tau_[MAXNF+5]; //definition of constants and couplings // const2_.ca_ = resconst::CA; // const2_.xnc_ = coupling::NC; // const2_.cf_ = resconst::Cf; // const2_.tr_ = resconst::NF/2.; // const2_.pi_ = M_PI; dyqcd_.pi_ = M_PI; dyqcd_.cf_ = resconst::Cf; dyqcd_.ca_ = resconst::CA; dyqcd_.tr_ = resconst::NF/2.; dyqcd_.xnc_ = coupling::NC; dyqcd_.nf_ = resconst::NF; // dycouplings_.alpha0_ = coupling::aemmz; // dycouplings_.xw_ = coupling::xw; // dycouplings_.sw_ = sqrt(coupling::xw); // sin_w // dycouplings_.cw_ = sqrt(1.-coupling::xw); // cos_w luminosity::init(); } double vjint::vint(double m, double pt, double y) { double q2 = m*m; //set scales and alpha strong scales::set(m, pt); scales::vjet(); /* if (opts.dynamicscale) { scales2_.xmur_ = sqrt(pow(opts.kmuren*m,2) + pow(opts.kpt_muren*pt,2)); scales2_.xmuf_ = sqrt(pow(opts.kmufac*m,2) + pow(opts.kpt_mufac*pt,2)); } else { scales2_.xmur_ = sqrt(pow(opts.kmuren*opts.rmass,2) + pow(opts.kpt_muren*pt,2)); scales2_.xmuf_ = sqrt(pow(opts.kmufac*opts.rmass,2) + pow(opts.kpt_mufac*pt,2)); } scales2_.xmur2_ = pow(scales2_.xmur_,2); scales2_.xmuf2_ = pow(scales2_.xmuf_,2); asnew_.as_ = LHAPDF::alphasPDF(scales2_.xmur_)/M_PI; */ //calculate logs of scales utils_scales_(q2); //calculate propagators double cw2 = 1.- coupling::xw; - if (opts.zerowidth) - { - sigs_.sigz_ = brz; // /(16.*cw2) - sigs_.sigw_ = brw; // /4. - sigs_.siggamma_ = 0.; - sigs_.sigint_ = 0.; - } - else - { + //if (opts.zerowidth) + // { + // sigs_.sigz_ = brz; // /(16.*cw2) + // sigs_.sigw_ = brw; // /4. + // sigs_.siggamma_ = 0.; + // sigs_.sigint_ = 0.; + // } + //else + // { //sigs_.sigz_ = brz*dymasses_.zwidth_*q2/(M_PI*coupling::zmass) / (pow(q2-pow(coupling::zmass,2),2)+pow(coupling::zmass,2)*pow(dymasses_.zwidth_,2)); // /(16.*cw2) //sigs_.sigw_ = brw*dymasses_.wwidth_*q2/(M_PI*coupling::wmass) / (pow(q2-pow(coupling::wmass,2),2)+pow(coupling::wmass,2)*pow(dymasses_.wwidth_,2)); // !/4. //sigs_.siggamma_ = em_.aemmz_/(3.*M_PI*q2); //sigs_.sigint_ = -em_.aemmz_/(6.*M_PI)*(q2-pow(coupling::zmass,2)) /(pow(q2-pow(coupling::zmass,2),2)+pow(coupling::zmass,2)*pow(dymasses_.zwidth_,2)) * (-1.+4.*coupling::xw)/(2.*sqrt(coupling::xw*cw2)); // !sqrt(sw2/cw2)/2. - mesq::setpropagators(m); - if (opts.nproc == 3) - sigs_.sigz_ = brz*dymasses_.zwidth_/(M_PI*coupling::zmass)*mesq::propZ; - else - sigs_.sigw_ = brw*dymasses_.wwidth_/(M_PI*coupling::wmass)*mesq::propW; - if (opts.useGamma) - { - sigs_.siggamma_ = coupling::aemmz/(3.*M_PI) * mesq::propG; - sigs_.sigint_ = -coupling::aemmz/(6.*M_PI)* mesq::propZG * (-1.+4.*coupling::xw)/(2.*sqrt(coupling::xw*cw2)); - } + mesq::setpropagators(m); + if (opts.nproc == 3) + sigs_.sigz_ = brz*dymasses_.zwidth_/(M_PI*coupling::zmass)*mesq::propZ; + else + sigs_.sigw_ = brw*dymasses_.wwidth_/(M_PI*coupling::wmass)*mesq::propW; + if (opts.useGamma) + { + sigs_.siggamma_ = coupling::aemmz/(3.*M_PI) * mesq::propG; + sigs_.sigint_ = -coupling::aemmz/(6.*M_PI)* mesq::propZG * (-1.+4.*coupling::xw)/(2.*sqrt(coupling::xw*cw2)); } + //} //set phase space variables // internal_.q_ = m; // internal_.q2_ = pow(m,2); // internal_.qt_ = pt; // yv_.yv_ = y; // yv_.expyp_ = phasespace::exppy;//exp(y); // yv_.expym_ = phasespace::expmy;//exp(-y);//1./yv_.expyp_; // if (opts.zerowidth) // internal_.q_ = opts.rmass; //call cross section calculation // int ord = opts.order - 1; // double res, err, chi2a; // qtdy_(res,err,chi2a,y,y,ord); // cout << setprecision(16) << "fortran " << m << " " << pt << " " << " " << y << " " << res << endl; double res = calc(m, pt, y); //cout << setprecision(16) << "C++ " << m << " " << pt << " " << " " << y << " " << res << endl; //Apply conversion factors: //ds/dqt = ds/dqt2 * dqt2/dqt //fb = 1000 * pb return 2*pt*res*1000.; } int xdelta_cubature(unsigned ndim, const double x[], void *data, unsigned ncomp, double f[]) { //f[0] = xdelta_(x); f[0] = vjint::delta(x[0]); return 0; } //int sing_cubature(unsigned ndim, const double x[], void *data, unsigned ncomp, double f[]) //{ // double zz[2]; // zz[0] = vjint::zmin*pow(vjint::zmax/vjint::zmin,x[0]); // double jacz1 = zz[0]*vjint::lz; // // zz[1] = vjint::zmin*pow(vjint::zmax/vjint::zmin,x[1]); // double jacz2 = zz[1]*vjint::lz; // // f[0] = sing_(zz)*jacz1*jacz2; // return 0; //} double vjint::calc(double m, double pt, double y) { clock_t begin_time, end_time; double q2 = phasespace::m2; // tm_.tm_ = sqrt(q2+pt*pt); //kinematical limits on qt (at y = 0) --> possibly not needed, since the phace space is generated within kinematical limits double z = q2/pow(opts.sroot,2); double xr = pow(1-z,2)-4*z*pow(pt/m,2); if (xr < 0) return 0.; //kinematical limits on y including qt double tmpx = (q2+pow(opts.sroot,2))/opts.sroot/phasespace::mt; double ymax = log((tmpx+sqrt(max(0.,pow(tmpx,2)-4.)))/2.); double ay = fabs(y); if (fabs(y) > ymax) return 0.; if (fabs(*(long*)& ay - *(long*)& ymax) < 2 ) //check also equality return 0.; //...compute as at order=nloop asp_.asp_ = asnew_.as_*M_PI; luminosity::cache(); //integration of the delta term //lower limit of integration for x2 double x2min=(q2-opts.sroot*phasespace::mt*phasespace::expmy)/(opts.sroot*phasespace::mt*phasespace::exppy-pow(opts.sroot,2)); logx2min = log(x2min); if (x2min >= 1. || x2min < 0.) { //cout << "error in x2min " << x2min << " m " << phasespace::m << " pt " << phasespace::qt << " y " << phasespace::y << endl; return 0.; } /* //pcubature integration const int ndimx = 1; //dimensions of the integral const int ncomp = 1; //components of the integrand void *userdata = NULL; double integral[1]; double error[1]; const int eval = 0; const double epsrel = min(1e-4,opts.pcubaccuracy); const double epsabs = 0.; //boundaries of integration double xmin[1] = {0.}; double xmax[1] = {1.}; begin_time = clock(); pcubature(ncomp, xdelta_cubature, userdata, ndimx, xmin, xmax, eval, epsabs, epsrel, ERROR_INDIVIDUAL, integral, error); end_time = clock(); double rdelta = integral[0]; double err = error[0]; if (opts.timeprofile) cout << setw(10) << "xdelta time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << setw(10) << "result" << setw(10) << rdelta << endl; */ begin_time = clock(); double rdelta = 0.; int xrule = opts.xrule; //start integration double ax = 0.; double bx = 1.; double cx = 0.5*(ax+bx); double mx = 0.5*(bx-ax); double jac = mx; for (int i = 0; i < xrule; i++) { double x = cx+mx*gr::xxx[xrule-1][i]; rdelta += delta(x) * jac * gr::www[xrule-1][i]; } end_time = clock(); if (opts.timeprofile) cout << setw(10) << "xdelta time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << setw(10) << "result" << setw(10) << rdelta << endl; //integration of non-delta(s2) terms (only at NLO) //initialise double rsing = 0.; begin_time = clock(); if (opts.order == 2) { rsing = sing(); /* ////pcubature integration //const int ndims = 2; //dimensions of the integral //// boundaries of integration //double zmn[2] = {zmin,zmin}; //double zmx[2] = {zmax,zmax}; //pcubature(ncomp, sing_cubature, userdata, // ndims, zmn, zmx, // eval, epsabs, 1e-4, ERROR_INDIVIDUAL, integral, error); //rsing = integral[0]; //err = sqrt(err*err + error[0]*error[0]); //// cout << m << " " << pt << " " << y << " " << integral[0] << " " << error[0] << endl; //gaussian quadrature double zz[2]; double az1 = zmin; double bz1 = zmax; double cz1=0.5*(az1+bz1); double mz1=0.5*(bz1-az1); for (int j = 0; j < z1rule; j++) { double z1 = cz1 + mz1*gr::xxx[z1rule-1][j]; double t = t1[j];//zmin*pow(zmax/zmin,z1); double jacz1=t*lz; zz[0]=t; double az2 = zmin; double bz2 = zmax; double cz2 = 0.5*(az2+bz2); double mz2 = 0.5*(bz2-az2); for (int jj = 0; jj < z2rule; jj++) { double z2 = cz2 + mz2*gr::xxx[z2rule-1][jj]; double t = t2[jj];//zmin*pow(zmax/zmin,z2); double jacz2 = t*lz; zz[1] = t; rsing=rsing+sing_(zz)*gr::www[z1rule-1][j]*gr::www[z2rule-1][jj] //rsing=rsing+sing(zz[0],zz[1])*gr::www[z1rule-1][j]*gr::www[z2rule-1][jj] *jacz1*jacz2*mz1*mz2; } } //cout << m << " " << pt << " " << y << " " << rsing << endl; */ rsing = rsing/2./M_PI;//*(asp_.asp_/2./M_PI); } else if (opts.order == 1) rsing = 0.; end_time = clock(); if (opts.timeprofile) cout << setw(10) << "rsing time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << setw(10) << "result" << setw(10) << rsing << endl; //final result double res = rdelta+rsing; //cout << m << " " << pt << " " << y << " " << res << endl; return res; } diff --git a/vjet/vjint.h b/vjet/vjint.h index 6466a14..07ac220 100644 --- a/vjet/vjint.h +++ b/vjet/vjint.h @@ -1,258 +1,259 @@ #ifndef vjint_h #define vjint_h #include extern "C" { void qtdy_(double &res, double &err, double &chi2a, double &y1, double &y2, int &ord); double xdelta_(const double *x); double sing_(double z[2]); void flavour_(void); void utilities_(double & sh, double & th, double & uh, double & q2, double & ss2); void utilities2_(double & uh, double & q2); void utilities3_(double & q2); void utilities_dilog_(double & sh, double & th, double & uh, double & q2); void utils_scales_(double & q2); void utils_fu_(double & uh, double & q2); void utils_dilog_(double & sh, double & th, double & uh, double & q2); void utils_(double & sh, double & th, double & uh, double & q2, double & ss2); //functions used in delta double aqg0_(double& sh, double& th, double& uh, double& q2); double agq0_(double& sh, double& th, double& uh, double& q2); double aqqb0_(double& sh, double& th, double& uh, double& q2); double bqg1_(double& sh, double& th, double& uh, double& q2); double bgq1_(double& sh, double& th, double& uh, double& q2); double bqg2_(double& sh, double& th, double& uh, double& q2); double bgq2_(double& sh, double& th, double& uh, double& q2); double cqg1_(double& sh, double& th, double& uh, double& q2); double cgq1_(double& sh, double& th, double& uh, double& q2); double cqg2_(double& sh, double& th, double& uh, double& q2); double cgq2_(double& sh, double& th, double& uh, double& q2); double bqg3_(double& sh, double& th, double& uh, double& q2); double bgq3_(double& sh, double& th, double& uh, double& q2); double bqqb1_(double& sh, double& th, double& uh, double& q2); double bqqb2_(double& sh, double& th, double& uh, double& q2); double cqqb1_(double& sh, double& th, double& uh, double& q2); double d0aa_(double& sh, double& th, double& uh, double& q2); double bqqb3_(double& sh, double& th, double& uh, double& q2); //functions used in sing double cgg1_(double& sh, double& th, double& uh, double& q2); double cgg1x_(double& sh, double& th, double& uh, double& q2); double cqg3_(double& sh, double& th, double& uh, double& q2, int& flag); double cgq3_(double& sh, double& th, double& uh, double& q2, int& flag); double cqqb2_(double& sh, double& th, double& uh, double& q2, int& flag); double cqqb2x_(double& sh, double& th, double& uh, double& q2, int& flag); double daa_(double& sh, double& th, double& uh, double& q2, int& flag); double daax_(double& sh, double& th, double& uh, double& q2, int& flag); double dab_(double& sh, double& th, double& uh, double& q2); double dabx_(double& sh, double& th, double& uh, double& q2); double dbb_(double& sh, double& th, double& uh, double& q2); double dbbx_(double& sh, double& th, double& uh, double& q2); double dac_(double& sh, double& th, double& uh, double& q2); double dad_(double& sh, double& th, double& uh, double& q2); double dbc_(double& sh, double& th, double& uh, double& q2); double dbd_(double& sh, double& th, double& uh, double& q2); double dcc_(double& sh, double& th, double& uh, double& q2); double ddd_(double& sh, double& th, double& uh, double& q2); double dcdll_(double& sh, double& th, double& uh, double& q2); double dcdllx_(double& sh, double& th, double& uh, double& q2); double dcdlr_(double& sh, double& th, double& uh, double& q2); double dcdlrx_(double& sh, double& th, double& uh, double& q2); double eac_(double& sh, double& th, double& uh, double& q2); double ebd_(double& sh, double& th, double& uh, double& q2); double ead_(double& sh, double& th, double& uh, double& q2); double ebc_(double& sh, double& th, double& uh, double& q2); extern struct { double pi_; double cf_; double ca_; double tr_; int xnc_; int nf_; } dyqcd_; // extern struct { // double gevpb_; // } gevpb_; // extern struct { // int flagch_; // } flagch_; // extern struct { // int iter_; // int locall_; // int nlocall_; // } vegint_; // extern struct { // int ih1_; // int ih2_; // } dypdf_; // extern struct { // int iord_; // } vjorder_; // extern struct { // int prodflag_; // } prodflag_; extern struct { double vud_; double vus_; double vub_; double vcd_; double vcs_; double vcb_; double vtd_; double vts_; double vtb_; } ckm_; //alpha EM (MZ) // extern struct { // double aemmz_; // } em_; extern struct { double eq_[5]; double alq_[5]; double arq_[5]; double ckm_[6][6]; double delta_[5][5]; double tau3_[5][5]; } quarks_; // extern struct { // double pi_; // double cf_; // double ca_; // double tr_; // double xnc_; // } const2_; // extern struct { // double xw_; // double cw_; // double sw_; // double alpha0_; // } dycouplings_; // extern struct { // double s_; // double ss_; // } dypara_; //variables /* extern struct { double amv_; double y1_; double y2_; double qtbis_; double gf_; double ppi_; double ssroot_; double sw2_; double aem_; double ic_; } cdyqt_; */ // extern struct { // double yv_; // double expyp_; // double expym_; // } yv_; // extern struct { // double tm_; // } tm_; extern struct { double xmur_; double xmuf_; double xmur2_; double xmuf2_; } scales2_; extern struct { double as_; } asnew_; extern struct { double asp_; } asp_; extern struct { double siggamma_; double sigint_; double sigz_; double sigw_; } sigs_; // extern struct { // double qt_; // double q_; // double q2_; // } internal_; // extern struct { // double x1_; // double x2_; // } fractions_; extern struct { double xlumgg_; double xlumqg_; double xlumgq_; double xlumqgtr_; double xlumgqtr_; double xlumqqb_; double xlumqqbtr_; double xlumqqbdbb_; double xlumqqbdbc_; double xlumqqbdcc_; double xlumqqbddd_; double xlumqqbLL_; double xlumqqbLR_; double xlumqq_; double xlumqqeaa_; double xlumqqebb_; double xlumqqead_; double xlumqqLL_; double xlumqqLR_; } luminosities_; } #pragma omp threadprivate(scales2_,asnew_,asp_,sigs_,luminosities_) namespace vjint { extern const double zmin; extern const double zmax; extern const double lz; extern int z1rule; extern int z2rule; extern double *t1; extern double *t2; extern double brz; extern double brw; extern double logx2min; #pragma omp threadprivate(logx2min) extern void init(); + extern void release(); extern double vint(double m, double pt, double y); extern double calc(double m, double pt, double y); extern double delta(double x); extern double sing(); } #endif diff --git a/vjet/vjloint.C b/vjet/vjloint.C index a1f0b15..4e8803f 100644 --- a/vjet/vjloint.C +++ b/vjet/vjloint.C @@ -1,685 +1,686 @@ #include "vjloint.h" #include "settings.h" #include "codata.h" #include "mcfm_interface.h" #include "mesq.h" #include "pdf.h" #include "scales.h" #include "phasespace.h" #include "omegaintegr.h" #include "cubature.h" #include "isnan.h" #include "gaussrules.h" #include "KinematicCuts.h" #include #include #include #include const double scutoff = 1e-6; using namespace std; double vjloint::muf; double vjloint::mur; void vjloint::init() { muf = opts.rmass*opts.kmufac; mur = opts.rmass*opts.kmures; } void vjloint::calc(const double x[5], double f[2]) { f[0] = 0.; f[1] = 0.; //generate phase space as m, qt, y, costh, phi_lep, x2 //Jacobian of the change of variables from the unitary hypercube x[6] to the m, qt, y, costh, phi_lep, x2 boundaries double jac = 1.; bool status; //phase space factors (should be (1/2/pi)^3 for each free particle) double wtvj=1./8./M_PI; //pq -> V+j phase space double wtv=1./8./M_PI/2./2./M_PI; //V-> ll phase space double wt=wtvj*wtv/2./M_PI; jac = jac * wt; double r3[3] = {x[0], x[1], x[2]}; //two alternatives for phase space generation /* status = phasespace::gen_mqty(r3, jac, true); phasespace::calcexpy(); //calculate exp(y) and exp(-y), since they are used in genV4p() and genx2() */ status = phasespace::gen_myqt(r3, jac, true); phasespace::calcmt(); //calculate mt, since it is used in genV4p() and genx2() if (!status) return; jac = jac *2.*phasespace::qt; //Set factorization and renormalization scales scales::set(phasespace::m, phasespace::qt); scales::mcfm(); muf = scales::fac; mur = scales::ren; /* //Set factorization and renormalization scales if (opts.dynamicscale) { muf = phasespace::m*opts.kmufac; mur = phasespace::m*opts.kmuren; double mur2 = mur*mur; scaleset_(mur2); } */ //Generate the boson 4-momentum phasespace::set_phiV(0.); phasespace::genV4p(); //move dx2 integration here //Calculate Bjorken x1 and x2 (integration is performed in dx2) status = phasespace::gen_x2(x[3], jac); if (!status) return; /* if (jac == 0.) { //cout << "x2 with jac = 0 " << phasespace::x2 << endl; return; } */ //Generate incoming partons phasespace::genp12(); //Generate jet from momentum conservation phasespace::genp5(); //reject event if any s(i,j) is too small double s15=2.*(phasespace::p1[3]*phasespace::p5[3]-phasespace::p1[0]*phasespace::p5[0]-phasespace::p1[1]*phasespace::p5[1]-phasespace::p1[2]*phasespace::p5[2]); double s25=2.*(phasespace::p2[3]*phasespace::p5[3]-phasespace::p2[0]*phasespace::p5[0]-phasespace::p2[1]*phasespace::p5[1]-phasespace::p2[2]*phasespace::p5[2]); //if (-s15 < cutoff_.cutoff_ || -s25 < cutoff_.cutoff_) if (-s15 < scutoff || -s25 < scutoff) { // cout << "failed s cut off " << s15 << " " << s25 << endl; return; } /* //6d integration ///////////////////// //perform dOmega integration (start loop on phi_lep, costh) double r2[2] = {x[3], x[4]}; phasespace::gen_costhphi(r2, jac); phasespace::genl4p(); //calculate V+j matrix elements double p[4][mxpart]; fillp(p); double msq[11][11]; if(opts.nproc == 3) qqb_z_g_(p,msq); else qqb_w_g_(p,msq); ///////////////////// */ /* //5d integration ///////////////////// omegaintegr::genV4p(); //--> this function calls genRFaxes for qt-prescription phasespace::genRFaxes(phasespace::CS); //-->overwrite RF axes //phasespace::genRFaxes(phasespace::naive); //generate phi phase space phasespace::gen_phi(x[4], jac); //start costh integration double msq_cth[11][11]; for (int j = 0; j < 2*MAXNF+1; j++) for (int k = 0; k < 2*MAXNF+1; k++) msq_cth[j][k] = 0.; vector cthmin; vector cthmax; phasespace::setcthbounds(phasespace::getcthmin(), phasespace::getcthmax()); omegaintegr::costhbound(phasespace::phi_lep, cthmin, cthmax); //!be carefull, this way costh is integrated according to a given boson rest frame (CS or others) vector::iterator itmn; vector::iterator itmx; itmn = cthmin.begin(); itmx = cthmax.begin(); for (; itmn != cthmin.end(); itmn++, itmx++) { //cout << *itmn << " " << *itmx << " " << cthmin.size() << endl; double cthc=0.5*(*itmn+*itmx); double cthm=0.5*(*itmx-*itmn); int cthrule = 4; for(int i=0; i < cthrule; i++) { double xcth = cthc+cthm*gr::xxx[cthrule-1][i]; //Generate leptons 4-momenta: p3 is the lepton and p4 is the antilepton phasespace::set_cth(xcth); //phasespace::genRFaxes(CS); phasespace::genl4p(); //calculate V+j matrix elements double p[4][mxpart]; fillp(p); double msq[11][11]; if(opts.nproc == 3) qqb_z_g_(p,msq); else qqb_w_g_(p,msq); double cth = xcth*(phasespace::y >= 0. ? 1 : -1); double sth = sqrt(max(0.,1.-cth*cth)); double s2th = 2*xcth*sth; double phi = phasespace::phi_lep*(phasespace::y > 0. ? 1 : -1); double cphi = cos(phi); double c2phi = 2*cphi*cphi-1.; double sphi = sqrt(max(0.,1.-cphi*cphi))*(phi>0?1:-1); double s2phi = 2*cphi*sphi; //Angular polynomials //NEWKIN( A5 ){ SinThCS sinth; Sin2PhiCS sin2ph; double calc(){ return 5. * (sinth()*sinth()*sin2ph() ) ; } }; //NEWKIN( A6 ){ Sin2ThCS sin2th; SinPhiCS sinph; double calc(){ return 4. * (sin2th()*sinph() ) ; } }; //NEWKIN( A7 ){ SinThCS sinth; SinPhiCS sinph; double calc(){ return 4. * (sinth()*sinph() ) ; } }; double pol = 1.; if (opts.helicity == 0) pol = 20./3.*(0.5-1.5*cth*cth) +2./3.; else if (opts.helicity == 1) pol = 5.*(s2th*cphi); else if (opts.helicity == 2) pol = 10.*(sth*sth*c2phi); else if (opts.helicity == 3) pol = 4.*(sth*cphi); else if (opts.helicity == 4) pol = 4.*cth; //cout << cth << " " << phi << endl; for (int j = 0; j < 2*MAXNF+1; j++) for (int k = 0; k < 2*MAXNF+1; k++) if (msq[k][j] != 0.) msq_cth[k][j] += msq[k][j] *gr::www[cthrule-1][i]*cthm * pol; } //end dcosth loop } //end loop on costh boundaries double msq[11][11]; for (int j = 0; j < 2*MAXNF+1; j++) for (int k = 0; k < 2*MAXNF+1; k++) msq[j][k] = msq_cth[j][k]; ///////////////////// */ //4d integration //dOmega integration omegaintegr::genV4p(); //--> this function calls genRFaxes for qt-prescription phasespace::genRFaxes(phasespace::CS); //--> overwrite RF axes: RF here determines the frame for the coefficients if opts.helicity != -1, and/or the RF for the costh boundaries //phasespace::genRFaxes(phasespace::naive); double msq_omega[11][11]; double msq_omega_m[11][11]; for (int j = 0; j < 2*MAXNF+1; j++) for (int k = 0; k < 2*MAXNF+1; k++) { msq_omega[j][k] = 0.; msq_omega_m[j][k] = 0.; } //start phi integration int phiintervals, phirule; if (opts.makecuts) { phiintervals = opts.phiintervals; phirule = opts.phirule; } else { phiintervals = 1; phirule = opts.vjphirule; } double phi1 = -M_PI; double phi2 = M_PI; double hphi=(phi2-phi1)/phiintervals; for(int i=0; i < phiintervals; i++) { double phimin = i*hphi+phi1; double phimax = (i+1)*hphi+phi1; double phic=0.5*(phimin+phimax); double phim=0.5*(phimax-phimin); for(int iphi = 0; iphi < phirule; iphi++) { double xphi = phic+phim*gr::xxx[phirule-1][iphi]; phasespace::set_philep(xphi); phasespace::calcphilep(); double phi, cphi, c2phi; //double sphi, s2phi; if (opts.helicity >= 0) { phi = phasespace::phi_lep*(phasespace::y > 0. ? 1 : -1); cphi = cos(phi); c2phi = 2*cphi*cphi-1.; //sphi = sqrt(max(0.,1.-cphi*cphi))*(phi>0?1:-1); //s2phi = 2*cphi*sphi; } //start costh integration vector cthmin; vector cthmax; phasespace::setcthbounds(phasespace::getcthmin(), phasespace::getcthmax()); //Allows for switching integration boundaries between positive and negative rapidity (currently not thread safe!!!) omegaintegr::costhbound(phasespace::phi_lep, cthmin, cthmax); //!be carefull, this way costh is integrated according to a given boson rest frame (CS or others) vector::iterator itmn; vector::iterator itmx; itmn = cthmin.begin(); itmx = cthmax.begin(); for (; itmn != cthmin.end(); itmn++, itmx++) { //cout << *itmn << " " << *itmx << " " << cthmin.size() << endl; double cthc=0.5*(*itmn+*itmx); double cthm=0.5*(*itmx-*itmn); int cthrule = 3; for(int i=0; i < cthrule; i++) { double xcth = cthc+cthm*gr::xxx[cthrule-1][i]; //Generate leptons 4-momenta: p3 is the lepton and p4 is the antilepton phasespace::set_cth(xcth); //phasespace::genRFaxes(CS); phasespace::genl4p(); //calculate V+j matrix elements double p[4][mxpart]; fillp(p); double msq[11][11]; if(opts.nproc == 3) //qqb_z_g_(p,msq); qqb_z1jet_(p,msq); else qqb_w_g_(p,msq); double cth, sth, s2th; if (opts.helicity >= 0) { cth = xcth*(phasespace::y >= 0. ? 1 : -1); sth = sqrt(max(0.,1.-cth*cth)); s2th = 2*cth*sth; } double poly = 1.; if (opts.helicity == 0) poly = 20./3.*(0.5-1.5*cth*cth) +2./3.; else if (opts.helicity == 1) poly = 5.*(s2th*cphi); else if (opts.helicity == 2) poly = 10.*(sth*sth*c2phi); else if (opts.helicity == 3) poly = 4.*(sth*cphi); else if (opts.helicity == 4) poly = 4.*cth; else if (opts.helicity > 4) poly = 0.; //Angular polynomials //NEWKIN( A5 ){ SinThCS sinth; Sin2PhiCS sin2ph; double calc(){ return 5. * (sinth()*sinth()*sin2ph() ) ; } }; //NEWKIN( A6 ){ Sin2ThCS sin2th; SinPhiCS sinph; double calc(){ return 4. * (sin2th()*sinph() ) ; } }; //NEWKIN( A7 ){ SinThCS sinth; SinPhiCS sinph; double calc(){ return 4. * (sinth()*sinph() ) ; } }; for (int j = 0; j < 2*MAXNF+1; j++) for (int k = 0; k < 2*MAXNF+1; k++) if (msq[k][j] != 0.) { msq_omega[k][j] += msq[k][j] *gr::www[cthrule-1][i]*cthm *gr::www[phirule-1][iphi]*phim; //msq_omega[k][j] += gr::www[cthrule-1][i]*cthm *gr::www[phirule-1][iphi]*phim; if (opts.helicity >= 0) msq_omega_m[k][j] += msq[k][j] *gr::www[cthrule-1][i]*cthm *gr::www[phirule-1][iphi]*phim * poly; } } //end dcosth loop } //end loop on costh boundaries } }//end philep integration //double msq[11][11]; //for (int j = 0; j < 2*MAXNF+1; j++) //for (int k = 0; k < 2*MAXNF+1; k++) //msq[j][k] = msq_omega[j][k]; ///////////////////// // Load central PDF and QCD coupling //if (pdferr) then //int npdf = 0; //dysetpdf_(npdf); //double gsqcentral=gsq; // skip PDF loop in the preconditioning phase //int maxpdf=0; //if (doFill.ne.0) maxpdf = totpdf-1 // start PDF loop // for (int np=0; np <= maxpdf; np++) // { // dysetpdf_(np); // hists_setpdf_(np); // intitialise xmsq to 0 //cout << muf << " " << x1 << " " << x2 << endl; // calculate PDFs double fx1[2*MAXNF+1],fx2[2*MAXNF+1]; fdist_(opts.ih1,phasespace::x1,muf,fx1); fdist_(opts.ih2,phasespace::x2,muf,fx2); double xmsq = convolute(fx1, fx2, msq_omega); double xmsq_m; if (opts.helicity >= 0) xmsq_m = convolute(fx1, fx2, msq_omega_m); double shad = pow(opts.sroot,2); xmsq *= gevfb/(2.*phasespace::x1*phasespace::x2*shad); xmsq_m *= gevfb/(2.*phasespace::x1*phasespace::x2*shad); //double fbGeV2 = 0.389379e12; //xmsq=xmsq*fbGeV2/(2.*phasespace::x1*phasespace::x2*shad); //f[np+1]=xmsq;; //if (doFill.ne.0) then // { // val=xmsq*wgt // hists_fill_(p3,p4,val); // } //} end PDFs loop //cout << phasespace::x2 << " " << xmsq << " " << jac << endl; if (isnan_ofast(xmsq)) { // cout << "xmsq in vjloint is nan" << endl; return; } f[0] = xmsq*jac; f[1] = xmsq_m*jac; return; } double vjloint::calcvegas(const double x[7]) { clock_t begin_time, end_time; begin_time = clock(); //generate phase space as m, qt, y, costh, phi_lep, x2 //Jacobian of the change of variables from the unitary hypercube x[6] to the m, qt, y, costh, phi_lep, x2 boundaries double jac = 1.; bool status; //phase space factors (should be (1/2/pi)^3 for each free particle) double wtvj=1./8./M_PI; //pq -> V+j phase space double wtv=1./8./M_PI/2./2./M_PI; //V-> ll phase space double wt=wtvj*wtv/2./M_PI; jac = jac * wt; double r3[3] = {x[0], x[1], x[2]}; //two alternatives for phase space generation //status = phasespace::gen_mqty(r3, jac, true); //phasespace::calcexpy(); //calculate exp(y) and exp(-y), since they are used in genV4p() and genx2() status = phasespace::gen_myqt(r3, jac, true); phasespace::calcmt(); //calculate mt, since it is used in genV4p() and genx2() if (!status) return 0.; jac = jac *2.*phasespace::qt; //Set factorization and renormalization scales scales::set(phasespace::m, phasespace::qt); scales::mcfm(); muf = scales::fac; mur = scales::ren; /* //Set factorization and renormalization scales if (opts.dynamicscale) { muf = phasespace::m*opts.kmufac; mur = phasespace::m*opts.kmuren; double mur2 = mur*mur; scaleset_(mur2); //set renormalization and factorization scales, and calculate ason2pi and ason4pi } */ //Generate the boson 4-momentum phasespace::set_phiV(-M_PI+2.*M_PI*x[6]); phasespace::genRFaxes(phasespace::naive); phasespace::genV4p(); //move dx2 integration here //Calculate Bjorken x1 and x2 (integration is performed in dx2) status = phasespace::gen_x2(x[5], jac); if (!status) { //cout << "x2 with jac = 0 " << phasespace::x2 << endl; return 0.; } //Generate incoming partons phasespace::genp12(); //Generate jet from momentum conservation phasespace::genp5(); //reject event if any s(i,j) is too small double s15=2.*(phasespace::p1[3]*phasespace::p5[3]-phasespace::p1[0]*phasespace::p5[0]-phasespace::p1[1]*phasespace::p5[1]-phasespace::p1[2]*phasespace::p5[2]); double s25=2.*(phasespace::p2[3]*phasespace::p5[3]-phasespace::p2[0]*phasespace::p5[0]-phasespace::p2[1]*phasespace::p5[1]-phasespace::p2[2]*phasespace::p5[2]); //if (-s15 < cutoff_.cutoff_ || -s25 < cutoff_.cutoff_) if (-s15 < scutoff || -s25 < scutoff) { // cout << "failed s cut off " << s15 << " " << s25 << endl; return 0.; } //perform dOmega integration (start loop on phi_lep, costh) double r2[2] = {x[3], x[4]}; phasespace::gen_costhphi(r2, jac); + phasespace::calcphilep(); phasespace::genl4p(); if (!Kinematics::Cuts::KeepThisEvent(phasespace::p3, phasespace::p4)) return 0.; //calculate V+j matrix elements double p[4][mxpart]; fillp(p); double msq[11][11]; if(opts.nproc == 3) //qqb_z_g_(p,msq); qqb_z1jet_(p,msq); else qqb_w_g_(p,msq); // Load central PDF and QCD coupling //if (pdferr) then //int npdf = 0; //dysetpdf_(npdf); //double gsqcentral=gsq; // skip PDF loop in the preconditioning phase //int maxpdf=0; //if (doFill.ne.0) maxpdf = totpdf-1 // start PDF loop // for (int np=0; np <= maxpdf; np++) // { // dysetpdf_(np); // hists_setpdf_(np); // intitialise xmsq to 0 //cout << muf << " " << x1 << " " << x2 << endl; // calculate PDFs double fx1[2*MAXNF+1],fx2[2*MAXNF+1]; fdist_(opts.ih1,phasespace::x1,muf,fx1); fdist_(opts.ih2,phasespace::x2,muf,fx2); double xmsq = convolute(fx1, fx2, msq); double shad = pow(opts.sroot,2); xmsq=xmsq*gevfb/(2.*phasespace::x1*phasespace::x2*shad); //f[np+1]=xmsq;; //if (doFill.ne.0) //{ double val=xmsq*jac; //} end PDFs loop if (isnan_ofast(xmsq)) { // cout << "xmsq in vjloint is nan" << endl; return 0.; } end_time = clock(); if (opts.timeprofile) cout << setw (3) << "m" << setw(10) << phasespace::m << setw(4) << "qt" << setw(10) << phasespace::qt << setw(8) << "result" << setw(10) << xmsq*jac << setw(10) << "tot time" << setw(10) << float( end_time - begin_time ) / CLOCKS_PER_SEC << endl; return xmsq*jac; } void vjloint::fillp(double p[4][mxpart]) { p[0][0] = phasespace::p1[0]; p[1][0] = phasespace::p1[1]; p[2][0] = phasespace::p1[2]; p[3][0] = phasespace::p1[3]; p[0][1] = phasespace::p2[0]; p[1][1] = phasespace::p2[1]; p[2][1] = phasespace::p2[2]; p[3][1] = phasespace::p2[3]; p[0][2] = phasespace::p3[0]; p[1][2] = phasespace::p3[1]; p[2][2] = phasespace::p3[2]; p[3][2] = phasespace::p3[3]; p[0][3] = phasespace::p4[0]; p[1][3] = phasespace::p4[1]; p[2][3] = phasespace::p4[2]; p[3][3] = phasespace::p4[3]; p[0][4] = phasespace::p5[0]; p[1][4] = phasespace::p5[1]; p[2][4] = phasespace::p5[2]; p[3][4] = phasespace::p5[3]; } double vjloint::convolute(double fx1[2*MAXNF+1], double fx2[2*MAXNF+1], double msq[2*MAXNF+1][2*MAXNF+1]) { double xmsq; if (opts.nproc == 1) { xmsq =fx1[0]*fx2[5]*msq[5][0]; xmsq+=fx1[0]*fx2[7]*msq[7][0]; xmsq+=fx1[0]*fx2[9]*msq[9][0]; xmsq+=fx1[2]*fx2[5]*msq[5][2]; xmsq+=fx1[2]*fx2[7]*msq[7][2]; xmsq+=fx1[2]*fx2[9]*msq[9][2]; xmsq+=fx1[4]*fx2[5]*msq[5][4]; xmsq+=fx1[4]*fx2[7]*msq[7][4]; xmsq+=fx1[4]*fx2[9]*msq[9][4]; xmsq+=fx1[5]*fx2[0]*msq[0][5]; xmsq+=fx1[5]*fx2[2]*msq[2][5]; xmsq+=fx1[5]*fx2[4]*msq[4][5]; xmsq+=fx1[5]*fx2[7]*msq[7][5]; xmsq+=fx1[5]*fx2[9]*msq[9][5]; xmsq+=fx1[7]*fx2[2]*msq[2][7]; xmsq+=fx1[7]*fx2[4]*msq[4][7]; xmsq+=fx1[7]*fx2[5]*msq[5][7]; xmsq+=fx1[9]*fx2[0]*msq[0][9]; xmsq+=fx1[9]*fx2[2]*msq[2][9]; xmsq+=fx1[9]*fx2[4]*msq[4][9]; xmsq+=fx1[9]*fx2[5]*msq[5][9]; } else if (opts.nproc == 2) { xmsq =fx1[1 ]*fx2[5 ]*msq[5 ][1 ]; xmsq+=fx1[1 ]*fx2[6 ]*msq[6 ][1 ]; xmsq+=fx1[1 ]*fx2[8 ]*msq[8 ][1 ]; xmsq+=fx1[1 ]*fx2[10]*msq[10][1 ]; xmsq+=fx1[3 ]*fx2[5 ]*msq[5 ][3 ]; xmsq+=fx1[3 ]*fx2[6 ]*msq[6 ][3 ]; xmsq+=fx1[3 ]*fx2[8 ]*msq[8 ][3 ]; xmsq+=fx1[3 ]*fx2[10]*msq[10][3 ]; xmsq+=fx1[5 ]*fx2[1 ]*msq[1 ][5 ]; xmsq+=fx1[5 ]*fx2[3 ]*msq[3 ][5 ]; xmsq+=fx1[5 ]*fx2[6 ]*msq[6 ][5 ]; xmsq+=fx1[5 ]*fx2[8 ]*msq[8 ][5 ]; xmsq+=fx1[5 ]*fx2[10]*msq[10][5 ]; xmsq+=fx1[6 ]*fx2[1 ]*msq[1 ][6 ]; xmsq+=fx1[6 ]*fx2[3 ]*msq[3 ][6 ]; xmsq+=fx1[6 ]*fx2[5 ]*msq[5 ][6 ]; xmsq+=fx1[8 ]*fx2[1 ]*msq[1 ][8 ]; xmsq+=fx1[8 ]*fx2[3 ]*msq[3 ][8 ]; xmsq+=fx1[8 ]*fx2[5 ]*msq[5 ][8 ]; xmsq+=fx1[10]*fx2[1 ]*msq[1 ][10]; xmsq+=fx1[10]*fx2[3 ]*msq[3 ][10]; xmsq+=fx1[10]*fx2[5 ]*msq[5 ][10]; } else if (opts.nproc == 3) { xmsq =fx1[0 ]*fx2[5 ]*msq[5 ][0 ]; xmsq+=fx1[0 ]*fx2[10]*msq[10][0 ]; xmsq+=fx1[1 ]*fx2[5 ]*msq[5 ][1 ]; xmsq+=fx1[1 ]*fx2[9 ]*msq[9 ][1 ]; xmsq+=fx1[2 ]*fx2[5 ]*msq[5 ][2 ]; xmsq+=fx1[2 ]*fx2[8 ]*msq[8 ][2 ]; xmsq+=fx1[3 ]*fx2[5 ]*msq[5 ][3 ]; xmsq+=fx1[3 ]*fx2[7 ]*msq[7 ][3 ]; xmsq+=fx1[4 ]*fx2[5 ]*msq[5 ][4 ]; xmsq+=fx1[4 ]*fx2[6 ]*msq[6 ][4 ]; xmsq+=fx1[5 ]*fx2[0 ]*msq[0 ][5 ]; xmsq+=fx1[5 ]*fx2[1 ]*msq[1 ][5 ]; xmsq+=fx1[5 ]*fx2[2 ]*msq[2 ][5 ]; xmsq+=fx1[5 ]*fx2[3 ]*msq[3 ][5 ]; xmsq+=fx1[5 ]*fx2[4 ]*msq[4 ][5 ]; xmsq+=fx1[5 ]*fx2[6 ]*msq[6 ][5 ]; xmsq+=fx1[5 ]*fx2[7 ]*msq[7 ][5 ]; xmsq+=fx1[5 ]*fx2[8 ]*msq[8 ][5 ]; xmsq+=fx1[5 ]*fx2[9 ]*msq[9 ][5 ]; xmsq+=fx1[5 ]*fx2[10]*msq[10][5 ]; xmsq+=fx1[6 ]*fx2[4 ]*msq[4 ][6 ]; xmsq+=fx1[6 ]*fx2[5 ]*msq[5 ][6 ]; xmsq+=fx1[7 ]*fx2[3 ]*msq[3 ][7 ]; xmsq+=fx1[7 ]*fx2[5 ]*msq[5 ][7 ]; xmsq+=fx1[8 ]*fx2[2 ]*msq[2 ][8 ]; xmsq+=fx1[8 ]*fx2[5 ]*msq[5 ][8 ]; xmsq+=fx1[9 ]*fx2[1 ]*msq[1 ][9 ]; xmsq+=fx1[9 ]*fx2[5 ]*msq[5 ][9 ]; xmsq+=fx1[10]*fx2[0 ]*msq[0 ][10]; xmsq+=fx1[10]*fx2[5 ]*msq[5 ][10]; } /* double xmsq = 0.; for (int j = 0; j < 2*MAXNF+1; j++) for (int k = 0; k < 2*MAXNF+1; k++) { //if (isnan_ofast(msq[k][j])) //cout << j << " " << k << " " << fx1[j] << " " << fx2[k] << " " << msq[k][j] << endl; if (msq[k][j] == 0.) continue; // gsq/gsqcentral correct for a possibly different value of alphas in the PDF (at O(alphas)) xmsq=xmsq+fx1[j]*fx2[k]*msq[k][j]; //*(gsq/gsqcentral) //cout << j << " " << k << " " << fx1[j] << " " << fx2[k] << " " << msq[k][j] << endl; } */ return xmsq; }