c++ output for custom models ?

Asked by Noam

Dear MG'ers,

I'm trying to understand what is the best way to get the matrix element offline at any point in the phase-space, from a c++ code.

The model I'm using is described here: https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Models/ggHFullLoop#no1. I think that the "output standalone_cpp" functionality has problems when it comes to such an "external" model with custom definitions and functions but I'm not sure.

So, my question divides into 2:
(1) can MG give a c++ formatted matrix element (averaged and squared) for models which do not ship with MG by default (e.g. ggHFullLoop) ?
(2) an alternative could be to link the objects coming from the generated fortran code, with a c++ code using the "extern" feature. The question is which function should be called and how to initialise the procedure ?

For (2) I actually managed to do something like that after having the process generated (see code below).
However, I'm not sure which of the fortran functions I should call from my c++ code. I have tried:
SMATRIX1(...) --> runtime problems with initialising NTRY(2)
DSIG1(...) --> same as for SMATRIX1
DSIG(...) --> executes well but seems to return sigma=0 always

Any prompt help would be highly appreciated !
Cheers,
Noam

////////////////////////////////////////////////
//// C++ code to link with MG fortran ////
//// Makefile is trivial //////////////////////
///////////////////////////////////////////////
#include <iostream>
using namespace std;
extern "C" {
        void smatrix1_(double** pp, double* ans);
}
extern "C" {
        double dsig1_(double** pp, double* wgt, int* imode);
}
extern "C" {
        double dsig_(double** pp, double* wgt, int* imode);
}

int main()
{
   double** pp = new double*[4];
   for (int i=0; i<4; ++i) pp[i] = new double[5];
   double* wgt = new double; *wgt = 1;
   int* imode = new int; *imode = 1;

   // example gg-->ttbar event, in the ggHFullLoop model with only the pseudo-scalar turned on, taken from the lhe file
   pp[0][0] = 0.00000000000E+00; pp[0][1] = 0.00000000000E+00; pp[0][2] = 0.40139316999E+03; pp[0][3] = 0.40139316999E+03;
   pp[1][0] = 0.00000000000E+00; pp[1][1] = 0.00000000000E+00; pp[1][2] = -0.25134778946E+03; pp[1][3] = 0.25134778946E+03;
   pp[2][0] = 0.50428638474E+02; pp[2][1] = 0.61397720859E+02; pp[2][2] = -0.18658101548E+03; pp[2][3] = 0.26623570956E+03;
   pp[3][0] = -0.50428638474E+02; pp[3][1] = -0.61397720859E+02; pp[3][2] = 0.33662639601E+03; pp[3][3] = 0.38650524989E+03;

   // DSIG(...) works but returns 0
   *imode = 1; // initialize ?
    dsig_(pp,wgt,imode);
   *imode = 0; // run ?
   double xs = dsig_(pp,wgt,imode);
   cout << "xs=" << xs << endl;

   // DSIG1(...) issues with initialization
   // *imode = 5; // should give only the matrix element
   // double xs = dsig1_(pp,wgt,imode);
   // cout << "xs=" << xs << endl;

   // SMATRIX1(...) issues with runtime initialization
   // smatrix1_(pp,ans);
   // cout << "ans=" << ans << endl;

   return 0;
}

Question information

Language:
English Edit question
Status:
Solved
For:
MadGraph5_aMC@NLO Edit question
Assignee:
No assignee Edit question
Solved by:
Olivier Mattelaer
Solved:
Last query:
Last reply:
Revision history for this message
Olivier Mattelaer (olivier-mattelaer) said :
#1

Dear Noam,

> (1) can MG give a c++ formatted matrix element (averaged and squared) for models which do not ship with MG by default (e.g ggHFullLoop) ?

For c++ output, we need to have a UFO model.

Now some UFO model have decide to rely on some external functions (like ggHFullLoop). Looks like they provide their function only for the Fortran output.
This therefore limits the possibility of what we can do with the model.

> (2) an alternative could be to link the objects coming from the generated fortran code, with a c++ code using the "extern" feature.

> SMATRIX1(...) --> runtime problems with initialising NTRY(2)
> DSIG1(...) --> same as for SMATRIX1
> DSIG(…) --> executes well but seems to return sigma=0 always

Looks like you are using the madevent output and not the standalone output.

> The question is which function should be called and how to initialise the procedure ?

You first need to initialise the model.
via the function initialise(PATH)
If you do not have this function, this means that you use an old version of the code. (or not the standalone output mode)
I have introduce it in order to have an easy way to link it against python.

Cheers,

Olivier

> <email address hidden>> wrote:
>
> New question #285523 on MadGraph5_aMC@NLO:
> https://answers.launchpad.net/mg5amcnlo/+question/285523
>
> Dear MG'ers,
>
> I'm trying to understand what is the best way to get the matrix element offline at any point in the phase-space, from a c++ code.
>
> The model I'm using is described here: https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Models/ggHFullLoop#no1.
> I think that the "output standalone_cpp" functionality has problems when it comes to such an "external" model with custom definitions and functions but I'm not sure, so, my question divides into 2:
> (1) can MG give a c++ formatted matrix element (averaged and squared) for models which do not ship with MG by default (e.g ggHFullLoop) ?
> (2) an alternative could be to link the objects coming from the generated fortran code, with a c++ code using the "extern" feature. The question is which function should be called and how to initialise the procedure ?
>
> For (2) I actually managed to do something like that after having the process generated (see code below).
> However, I'm not sure which of the fortran functions I should call from my c++ code. I have tried:
> SMATRIX1(...) --> runtime problems with initialising NTRY(2)
> DSIG1(...) --> same as for SMATRIX1
> DSIG(...) --> executes well but seems to return sigma=0 always
>
> Any prompt help would be highly appreciated !
> Cheers,
> Noam
>
>
> ////////////////////////////////////////////////
> //// C++ code to link with MG fortran ////
> //// Makefile is trivial //////////////////////
> ///////////////////////////////////////////////
> #include <iostream>
> using namespace std;
> extern "C" {
> void smatrix1_(double** pp, double* ans);
> }
> extern "C" {
> double dsig1_(double** pp, double* wgt, int* imode);
> }
> extern "C" {
> double dsig_(double** pp, double* wgt, int* imode);
> }
>
> int main()
> {
> double** pp = new double*[4];
> for (int i=0; i<4; ++i) pp[i] = new double[5];
> double* wgt = new double; *wgt = 1;
> int* imode = new int; *imode = 1;
>
> // example gg-->ttbar event taken from the lhe file
> pp[0][0] = 0.00000000000E+00; pp[0][1] = 0.00000000000E+00; pp[0][2] = 0.40139316999E+03; pp[0][3] = 0.40139316999E+03;
> pp[1][0] = 0.00000000000E+00; pp[1][1] = 0.00000000000E+00; pp[1][2] = -0.25134778946E+03; pp[1][3] = 0.25134778946E+03;
> pp[2][0] = 0.50428638474E+02; pp[2][1] = 0.61397720859E+02; pp[2][2] = -0.18658101548E+03; pp[2][3] = 0.26623570956E+03;
> pp[3][0] = -0.50428638474E+02; pp[3][1] = -0.61397720859E+02; pp[3][2] = 0.33662639601E+03; pp[3][3] = 0.38650524989E+03;
>
> // DSIG(...) works but returns 0
> *imode = 1; // initialize ?
> dsig_(pp,wgt,imode);
> *imode = 0; // run ?
> double xs = dsig_(pp,wgt,imode);
> cout << "xs=" << xs << endl;
>
> // DSIG1(...) issues with initialization
> // *imode = 5; // should give only the matrix element
> // double xs = dsig1_(pp,wgt,imode);
> // cout << "xs=" << xs << endl;
>
> // SMATRIX1(...) issues with runtime initialization
> // smatrix1_(pp,ans);
> // cout << "ans=" << ans << endl;
>
> return 0;
> }
>
> --
> You received this question notification because you are an answer
> contact for MadGraph5_aMC@NLO.

Revision history for this message
Noam (hod-7) said :
#2

Dear Olivier,

Many thanks for the prompt reply !

Yes, I was looking at the madevet output.

Now, with running the sctipt:
------------------------------------------------------------------------------
import model Higgs_Effective_Couplings_FormFact
generate g g > t t~ / h QED=99 QCD=99
output standalone
------------------------------------------------------------------------------
I get the correct code generated:
- bin
- TemplateVersion.txt
- MGMEVersion.txt
- lib
- __init__.py
- Cards
- Source
- SubProcesses

but i don't see any initialise(...) function there - what am I missing ?

Also, from your answer it sounds like the procedure I'm after should be easy from python.
If so, can you please let me know how I can get the ME^2 value in python while plugging in the particles 4-momenta?

Cheers,
Noam

Revision history for this message
Best Olivier Mattelaer (olivier-mattelaer) said :
#3

Hi Naom,

The initialise function is part of the matrix.f file which should be present in each of the SubProcesses/P… directory.
If you do not have it, please check that you are running the latest version of the code.

> Also, from your answer it sounds like the procedure I'm after should be easy from python.
> If so, can you please let me know how I can get the ME^2 value in python while plugging in the particles 4-momenta?

Sure. This python interface is based on f2py (which is part of numpy and requires python-devel package on linux).

Just go on SubProcesses/P… directory and type
make matrix2py.so

Then you should have a library that you can link trough python.
Here is an example on how to write a valid python code calling that matrix element:

import matrix2py

def invert_momenta(p):
        """ fortran/C-python do not order table in the same order"""
        new_p = []
        for i in range(len(p[0])): new_p.append([0]*len(p))
        for i, onep in enumerate(p):
            for j, x in enumerate(onep):
                new_p[j][i] = x
        return new_p

matrix2py.initialise('../../Cards/param_card.dat')
p = [[ 0.5000000E+03, 0.0000000E+00, 0.0000000E+00, 0.5000000E+03],
     [ 0.5000000E+03, 0.0000000E+00, 0.0000000E+00, -0.5000000E+03],
     [ 0.5000000E+03, 0.1109243E+03, 0.4448308E+03, -0.1995529E+03],
     [ 0.5000000E+03, -0.1109243E+03, -0.4448308E+03, 0.1995529E+03]]

P =invert_momenta(p)
alphas = 0.13
nhel = 0 # means sum over all helicity
me2 = matrix2py.get_me(P, alphas, nhel)
print me2

Cheers,

Olivier

> On Feb 15, 2016, at 00:51, Noam <email address hidden> wrote:
>
> Question #285523 on MadGraph5_aMC@NLO changed:
> https://answers.launchpad.net/mg5amcnlo/+question/285523
>
> Status: Answered => Open
>
> Noam is still having a problem:
> Dear Olivier,
>
> Many thanks for the prompt reply !
>
> Yes, I was looking at the madevet output.
>
> Now, with running the sctipt:
> ------------------------------------------------------------------------------
> import model Higgs_Effective_Couplings_FormFact
> generate g g > t t~ / h QED=99 QCD=99
> output standalone
> ------------------------------------------------------------------------------
> I get the correct code generated:
> - bin
> - TemplateVersion.txt
> - MGMEVersion.txt
> - lib
> - __init__.py
> - Cards
> - Source
> - SubProcesses
>
> but i don't see any initialise(...) function there - what am I missing ?
>
> Also, from your answer it sounds like the procedure I'm after should be easy from python.
> If so, can you please let me know how I can get the ME^2 value in python while plugging in the particles 4-momenta?
>
> Cheers,
> Noam
>
> --
> You received this question notification because you are an answer
> contact for MadGraph5_aMC@NLO.

Revision history for this message
Noam (hod-7) said :
#4

Dear Olivier,
Many thanks !
This is super useful.

Would still be good to know how to initialise matrix.o in a c++ code but given that I can do simple things with pyROOT then it is not a priori needed... I have some ideas on how to do it but I leave it aside for now.

Just a small question about your 4-momenta assignment - do I read it correctly that
p = [[ p1e, p1x, p1y, p1z],
       [ p2e, p2x, p2y, p2z],
     [ p3e, p3x, p3y, p3z],
     [ p4e, p4x, p4y, p4z]]
where p1,p2 are incoming and p3,p4 are outgoing ? (in my case p1+p2=g+g and p3+p4=t+t~) ?

Cheers,
Noam

Revision history for this message
Noam (hod-7) said :
#5

Thanks Olivier Mattelaer, that solved my question.