Merge lp:~maddevelopers/mg5amcnlo/python_syscalc into lp:~maddevelopers/mg5amcnlo/2.5.0

Proposed by Olivier Mattelaer
Status: Merged
Merged at revision: 291
Proposed branch: lp:~maddevelopers/mg5amcnlo/python_syscalc
Merge into: lp:~maddevelopers/mg5amcnlo/2.5.0
Diff against target: 2693 lines (+1721/-339) (has conflicts)
19 files modified
Template/LO/Cards/run_card.dat (+1/-1)
Template/LO/SubProcesses/reweight.f (+6/-6)
UpdateNotes.txt (+15/-0)
VERSION (+6/-0)
madgraph/interface/amcatnlo_run_interface.py (+2/-94)
madgraph/interface/common_run_interface.py (+520/-37)
madgraph/interface/madevent_interface.py (+13/-105)
madgraph/interface/madgraph_interface.py (+2/-2)
madgraph/interface/reweight_interface.py (+95/-38)
madgraph/iolibs/export_fks.py (+2/-1)
madgraph/iolibs/export_v4.py (+2/-0)
madgraph/madevent/gen_crossxhtml.py (+4/-4)
madgraph/various/banner.py (+9/-28)
madgraph/various/cluster.py (+2/-1)
madgraph/various/lhe_parser.py (+220/-8)
madgraph/various/misc.py (+85/-2)
madgraph/various/systematics.py (+724/-0)
tests/acceptance_tests/test_cmd_madevent.py (+10/-9)
tests/input_files/run_card_matching.dat (+3/-3)
Text conflict in UpdateNotes.txt
Text conflict in VERSION
Text conflict in madgraph/various/misc.py
To merge this branch: bzr merge lp:~maddevelopers/mg5amcnlo/python_syscalc
Reviewer Review Type Date Requested Status
Rikkert Frederix Needs Fixing
Eleni Vryonidou Approve
Valentin Hirschi Pending
Review via email: mp+302735@code.launchpad.net

Description of the change

This version allows to compute systematics error band on both LO and NLO sample.

For LO code, this is run automatically if 'use_syst' is set on True in the run_card.
For NLO code, this need to be called manually via the command 'systematics RUN_XX OPTIONS'
The sample need to be generated with the options 'store_rwgt_info=True'

The computation can also be called outside of madgraph via the code
madgraph/various/systematics.py INPUT.LHE[.GZ] OUTPUT.LHE[.GZ] OPTIONS

Here is the help of the systematics function such that you can see the options/make comment on this help if this is not clear/ comment on the default value.

INFO: syntax: systematics RUN_NAME [OUTPUT] [options]
INFO: -- Run the systematics run on the run_name run.
INFO: RUN_NAME can be a path to a lhef file.
INFO: OUTPUT can be the path to the output lhe file. we overwritte the input file otherwise
INFO:
INFO: options: (value written are default)
INFO:
INFO: --mur=0.5,1,2 # specify the values for renormalisation scale variation
INFO: --muf=0.5,1,2 # specify the values for factorisation scale variation
INFO: --alps=1 # specify the values for MLM emission scale variation
INFO: --dyn=-1,1,2,3,4 # specify the dynamical schemes to use.
INFO: # -1 is the one used by the sample.
INFO: # > 0 correspond to options of dynamical_scale_choice of the run_card.
INFO: --pdf=errorset # specify the pdfs to use for pdf variation. (see below)
INFO: --together=mur,muf,dyn # which parameter should we vary together to have all uncorrelated combination of the variations
INFO: --from_card # use the information from the run_card (LO only).
INFO:
INFO: Allowed value for the pdf options:
INFO: central : Do not perform any pdf variation
INFO: errorset : runs over the errorset
INFO: 244800 : runs over the associated set and his errorset
INFO: 244800@0 : runs over the associated set ONLY
INFO: CT10 : runs over the associated set and his errorset
INFO: CT10@0 : runs over the associated set ONLY
INFO: CT10@X : runs over the Xth set of the associated error set
INFO: XX,YY,ZZ : runs over the sets for XX,YY,ZZ (those three follows above syntax)

Cheers,

Olivier

To post a comment you must log in.
294. By Olivier Mattelaer

making the code runnning correctly on cluster mode

295. By Olivier Mattelaer

forget to push the last minut changes in the pdf syntax

296. By Olivier Mattelaer

merge with latest 2.5.0 version

Revision history for this message
Valentin Hirschi (valentin-hirschi) wrote :
Download full text (105.4 KiB)

Hi Olivier,

a)

I tried running everything out of the box for p p > e+ ve and python itself
crashed (so the error was not handled), because I guess one cannot use your
py-syscalc without lhapdf. I got

terminate called after throwing an instance of 'LHAPDF::ReadError'
  what(): Info file not found for PDF set 'NNPDF23_lo_as_0130_qed'

So the case of lhapdf not being used should be better handled.

Also, in the run_card, the commentary of the entry

NNPDF23_nlo_as_0116_mc = sys_pdf # matching scales

is not correct. And it is not clear what the user is supposed to or can put
for this field. It seems that putting the LHAID works as well as putting
directly the name of the pdf. Is this also true when using the old C++
syscalc?
The commentary of this entry should clarify this point.

Also, when putting a PDF set in 'sys_pdf' that I don't have, the codes
doesn't try to download it (unless of course this is also the PDF set that
I want to use for my central value).
It would be a nice feature if it did, because as of now the code simply
crashes when doing the systematics.
There should at least be a check that the PDF is available.

This comment applies both for LO and NLO.

b)

The help of the command 'systematics' is nice. I would maybe rephrase the
message (which is tricky for users not used to that)

--together=mur,muf,dyn # which parameter should we vary together to have
all uncorrelated combination of the variations
to

'lists the parameter that must be varied simultaneously so as to compute
the weights for all combinations of their variations'.

but up to you.

c)

At NLO, I tried

systematics run_02 --pdf=21100 --together=mur,muf

on p p > e+ ve [QCD] and it crashed with:

WARNING: program
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
/Users/valentin/Documents/Work/MG5/python_syscalc/PROCNLO_loop_sm_0/bin/internal/systematics.py
events.lhe.gz ./tmp_1_events.lhe.gz --pdf=21100 --together=mur,muf
--start_event=2500 --stop_event=5000 --result=./log_sys_1.txt
--lhapdf_config=/Users/valentin/Documents/HEP_softs/LHAPDF/LHAPDF-6.1.5_installation/bin/lhapdf-config
launch ends with non zero status: 1. Stop all computation

There seems to be a 'launch' too many in the command no?

I tried to run it by hand without the 'launch', but I got:

    pdfset = lhapdf.mkPDF(int(data)).set()
  File "lhapdf.pyx", line 469, in lhapdf.mkPDF (lhapdf.cpp:7253)
  File "lhapdf.pyx", line 454, in lhapdf.mkPDF_lhaid (lhapdf.cpp:7044)
RuntimeError: Empty PDF file name given to Info::load

On Thu, Aug 11, 2016 at 4:55 PM, Olivier Mattelaer <
<email address hidden>> wrote:

> Olivier Mattelaer has proposed merging lp:~maddevelopers/mg5amcnlo/python_syscalc
> into lp:~maddevelopers/mg5amcnlo/2.5.0.
>
> Requested reviews:
> Eleni Vryonidou (evryonidou)
> Rikkert Frederix (frederix)
> Valentin Hirschi (valentin-hirschi)
>
> For more details, see:
> https://code.launchpad.net/~maddevelopers/mg5amcnlo/
> python_syscalc/+merge/302735
>
> This version allows to compute systematics error band on both LO and NLO
> sample.
>
> For LO code, this is run automatically if 'use_syst' is set on True in the
> run_car...

297. By Olivier Mattelaer

Fix related to the review of Valentin + fixing reweighting for FxFx

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :
Download full text (109.7 KiB)

Hi Valentin,

Thanks for this review.

> So the case of lhapdf not being used should be better handled.

We actually do not need to run with lhapdf, just to have the lhapdf (version6) available.

> Also, in the run_card, the commentary of the entry
> NNPDF23_nlo_as_0116_mc = sys_pdf # matching scales
> is not correct

fixed

> It seems that putting the LHAID works as well as putting
> directly the name of the pdf. Is this also true when using the old C++
> syscalc?
> The commentary of this entry should clarify this point.

This is not a valid input for SysCalc. So I will not mention it here.

> Also, when putting a PDF set in 'sys_pdf' that I don't have, the codes
> doesn't try to download it (unless of course this is also the PDF set that
> I want to use for my central value).
> It would be a nice feature if it did, because as of now the code simply
> crashes when doing the systematics.

Done. I also automatically load the central if the run was not performed with lhapdf.
(knowing that nnpdf is likely to be slightly off due to their bug in lhapdf.)

> The help of the command 'systematics' is nice. I would maybe rephrase the
> message

Done

> pdfset = lhapdf.mkPDF(int(data)).set()
> File "lhapdf.pyx", line 469, in lhapdf.mkPDF (lhapdf.cpp:7253)
> File "lhapdf.pyx", line 454, in lhapdf.mkPDF_lhaid (lhapdf.cpp:7044)
> RuntimeError: Empty PDF file name given to Info::load

I do not reproduce this. Looks like either some PDF sets are missing or (worse) corrupted
I have face as well some problem with some lhapdf set so I have use another method
to load them and it fixes the problem that i faced.

Cheers,

Olivier

> On Aug 19, 2016, at 07:21, Valentin Hirschi <email address hidden> wrote:
>
> Hi Olivier,
>
> a)
>
> I tried running everything out of the box for p p > e+ ve and python itself
> crashed (so the error was not handled), because I guess one cannot use your
> py-syscalc without lhapdf. I got
>
> terminate called after throwing an instance of 'LHAPDF::ReadError'
> what(): Info file not found for PDF set 'NNPDF23_lo_as_0130_qed'
>
> So the case of lhapdf not being used should be better handled.
>
> Also, in the run_card, the commentary of the entry
>
> NNPDF23_nlo_as_0116_mc = sys_pdf # matching scales
>
> is not correct. And it is not clear what the user is supposed to or can put
> for this field. It seems that putting the LHAID works as well as putting
> directly the name of the pdf. Is this also true when using the old C++
> syscalc?
> The commentary of this entry should clarify this point.
>
> Also, when putting a PDF set in 'sys_pdf' that I don't have, the codes
> doesn't try to download it (unless of course this is also the PDF set that
> I want to use for my central value).
> It would be a nice feature if it did, because as of now the code simply
> crashes when doing the systematics.
> There should at least be a check that the PDF is available.
>
> This comment applies both for LO and NLO.
>
> b)
>
> The help of the command 'systematics' is nice. I would maybe rephrase the
> message (which is tricky for users not used to that)
>
> --together=mur,muf,dyn # which parameter should we vary together to hav...

Revision history for this message
Valentin Hirschi (valentin-hirschi) wrote :
Download full text (116.9 KiB)

> Hi Valentin,
>
> Thanks for this review.
>
> > So the case of lhapdf not being used should be better handled.
>
>
> We actually do not need to run with lhapdf, just to have the lhapdf (version6)
> available.

I know what I meant was that if I don't have lhapdf (or only lhapdf5) on my system, then systematics crashes with the following message:

UnboundLocalError : local variable 'lhapdf_libdir' referenced before assignment

( File "/Users/valentin/Documents/Work/MG5/python_syscalc/madgraph/various/misc.py", line 1637, in import_python_lhapdf
    candidates=[dirname for dirname in os.listdir(lhapdf_libdir+'64') \)

It would be nice if this situation could be detected before the crash and if a message would pop up warning the user that systematics are bypassed because he doesn't have lhapdf and that once he will have installed it, he can still rerun systematics independently on his results already produced by using the interactive madevent interface.

>
> > Also, in the run_card, the commentary of the entry
> > NNPDF23_nlo_as_0116_mc = sys_pdf # matching scales
> > is not correct
>
>
> fixed
>
> > It seems that putting the LHAID works as well as putting
> > directly the name of the pdf. Is this also true when using the old C++
> > syscalc?
> > The commentary of this entry should clarify this point.
>
> This is not a valid input for SysCalc. So I will not mention it here.

Ok, and it would be indeed to complicated to explain in which situation the user can put an lhaid there, I agree. Too bad.

> > Also, when putting a PDF set in 'sys_pdf' that I don't have, the codes
> > doesn't try to download it (unless of course this is also the PDF set that
> > I want to use for my central value).
> > It would be a nice feature if it did, because as of now the code simply
> > crashes when doing the systematics.
>
> Done. I also automatically load the central if the run was not performed with
> lhapdf.
> (knowing that nnpdf is likely to be slightly off due to their bug in lhapdf.)

Excellent, I tested it and it works.

> > The help of the command 'systematics' is nice. I would maybe rephrase the
> > message
>
> Done
>
> > pdfset = lhapdf.mkPDF(int(data)).set()
> > File "lhapdf.pyx", line 469, in lhapdf.mkPDF (lhapdf.cpp:7253)
> > File "lhapdf.pyx", line 454, in lhapdf.mkPDF_lhaid (lhapdf.cpp:7044)
> > RuntimeError: Empty PDF file name given to Info::load
>
> I do not reproduce this. Looks like either some PDF sets are missing or
> (worse) corrupted
> I have face as well some problem with some lhapdf set so I have use another
> method
> to load them and it fixes the problem that i faced.

Ok, now at NLO, I crash on:

AttributeError : 'Event' object has no attribute 'nloweight'
[...]
  File "/Users/valentin/Documents/Work/MG5/python_syscalc/madgraph/various/systematics.py", line 583, in get_nlo_wgt
    nloinfo = event.parse_nlo_weight()
  File "/Users/valentin/Documents/Work/MG5/python_syscalc/madgraph/various/lhe_parser.py", line 1134, in parse_nlo_weight
    return self.nloweight
AttributeError: 'Event' object has no attribute 'nloweight'

This happened both with and without PDF variations in my generation (I assume you require the user t...

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :

> I know what I meant was that if I don't have lhapdf (or only lhapdf5) on my
> system, then systematics crashes with the following message:

ok this should be fixed now.

> Ok, now at NLO, I crash on:
> AttributeError: 'Event' object has no attribute 'nloweight'
>

This is because, you didnot put 'store_rwgt_info' on True in the NLo run_card.
Impossible to compute systematics in that case.
I have put in place a nicer error message for that situation.

> This happened both with and without PDF variations in my generation (I assume
> you require the user to having generated events with both variations turned
> on, it would be great if you could safe-check this).

No you can have both variation turned off.

> By the way, additional general question:
> If there is already a bunch of weights in the event, but only some are missing
> given the inputs provided to 'systematics', will you recompute all of them or
> do you automatically filter them out?
> It's ok if you recompute all of them, but I was wondering if you had optimized
> this bit.

No I'm not smart at all on that point of view, I recompute them and add them to the event file.

Cheers,

Olivier

298. By Olivier Mattelaer

apply change related to round2 of Valentin review

Revision history for this message
Eleni Vryonidou (evryonidou) wrote :
Download full text (293.5 KiB)

Hi Olivier,

I tried getting a fresh branch of python_syscalc but trying to run fails with this error:

ImportError : No module named various.systematics

And in the log file:

 File "/Users/evryonidou/Desktop/python_syscalc/check/bin/internal/common_run_interface.py", line 1336, in do_systematics
    import internal.various.systematics as systematics
ImportError: No module named various.systematics

So I couldn’t go further with any other checks… Do you have any idea what this problem is?

Cheers,

Eleni

> On 12 Aug 2016, at 01:55, Olivier Mattelaer <email address hidden> wrote:
>
> Olivier Mattelaer has proposed merging lp:~maddevelopers/mg5amcnlo/python_syscalc into lp:~maddevelopers/mg5amcnlo/2.5.0.
>
> Requested reviews:
> Eleni Vryonidou (evryonidou)
> Rikkert Frederix (frederix)
> Valentin Hirschi (valentin-hirschi)
>
> For more details, see:
> https://code.launchpad.net/~maddevelopers/mg5amcnlo/python_syscalc/+merge/302735
>
> This version allows to compute systematics error band on both LO and NLO sample.
>
> For LO code, this is run automatically if 'use_syst' is set on True in the run_card.
> For NLO code, this need to be called manually via the command 'systematics RUN_XX OPTIONS'
> The sample need to be generated with the options 'store_rwgt_info=True'
>
> The computation can also be called outside of madgraph via the code
> madgraph/various/systematics.py INPUT.LHE[.GZ] OUTPUT.LHE[.GZ] OPTIONS
>
> Here is the help of the systematics function such that you can see the options/make comment on this help if this is not clear/ comment on the default value.
>
> INFO: syntax: systematics RUN_NAME [OUTPUT] [options]
> INFO: -- Run the systematics run on the run_name run.
> INFO: RUN_NAME can be a path to a lhef file.
> INFO: OUTPUT can be the path to the output lhe file. we overwritte the input file otherwise
> INFO:
> INFO: options: (value written are default)
> INFO:
> INFO: --mur=0.5,1,2 # specify the values for renormalisation scale variation
> INFO: --muf=0.5,1,2 # specify the values for factorisation scale variation
> INFO: --alps=1 # specify the values for MLM emission scale variation
> INFO: --dyn=-1,1,2,3,4 # specify the dynamical schemes to use.
> INFO: # -1 is the one used by the sample.
> INFO: # > 0 correspond to options of dynamical_scale_choice of the run_card.
> INFO: --pdf=errorset # specify the pdfs to use for pdf variation. (see below)
> INFO: --together=mur,muf,dyn # which parameter should we vary together to have all uncorrelated combination of the variations
> INFO: --from_card # use the information from the run_card (LO only).
> INFO:
> INFO: Allowed value for the pdf options:
> INFO: central : Do not perform any pdf variation
> INFO: errorset : runs over the errorset
> INFO: 244800 : runs over the associated set and his errorset
> INFO: 244800@0 : runs over the associated set ONLY
> INFO: CT10 : runs over the associated set and his errorset
> INFO: CT10@0 : runs over the associated set ONLY
> INFO: CT10@X : runs over the Xth set of ...

299. By Olivier Mattelaer

fix an import problem

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :
Download full text (301.7 KiB)

Thanks to have spot this.

It should be fix now.

Cheers,

Olivier
> On Aug 22, 2016, at 18:30, Eleni Vryonidou <email address hidden> wrote:
>
> Hi Olivier,
>
> I tried getting a fresh branch of python_syscalc but trying to run fails with this error:
>
> ImportError : No module named various.systematics
>
> And in the log file:
>
> File "/Users/evryonidou/Desktop/python_syscalc/check/bin/internal/common_run_interface.py", line 1336, in do_systematics
> import internal.various.systematics as systematics
> ImportError: No module named various.systematics
>
> So I couldn’t go further with any other checks… Do you have any idea what this problem is?
>
> Cheers,
>
> Eleni
>
>
>> On 12 Aug 2016, at 01:55, Olivier Mattelaer <email address hidden> wrote:
>>
>> Olivier Mattelaer has proposed merging lp:~maddevelopers/mg5amcnlo/python_syscalc into lp:~maddevelopers/mg5amcnlo/2.5.0.
>>
>> Requested reviews:
>> Eleni Vryonidou (evryonidou)
>> Rikkert Frederix (frederix)
>> Valentin Hirschi (valentin-hirschi)
>>
>> For more details, see:
>> https://code.launchpad.net/~maddevelopers/mg5amcnlo/python_syscalc/+merge/302735
>>
>> This version allows to compute systematics error band on both LO and NLO sample.
>>
>> For LO code, this is run automatically if 'use_syst' is set on True in the run_card.
>> For NLO code, this need to be called manually via the command 'systematics RUN_XX OPTIONS'
>> The sample need to be generated with the options 'store_rwgt_info=True'
>>
>> The computation can also be called outside of madgraph via the code
>> madgraph/various/systematics.py INPUT.LHE[.GZ] OUTPUT.LHE[.GZ] OPTIONS
>>
>> Here is the help of the systematics function such that you can see the options/make comment on this help if this is not clear/ comment on the default value.
>>
>> INFO: syntax: systematics RUN_NAME [OUTPUT] [options]
>> INFO: -- Run the systematics run on the run_name run.
>> INFO: RUN_NAME can be a path to a lhef file.
>> INFO: OUTPUT can be the path to the output lhe file. we overwritte the input file otherwise
>> INFO:
>> INFO: options: (value written are default)
>> INFO:
>> INFO: --mur=0.5,1,2 # specify the values for renormalisation scale variation
>> INFO: --muf=0.5,1,2 # specify the values for factorisation scale variation
>> INFO: --alps=1 # specify the values for MLM emission scale variation
>> INFO: --dyn=-1,1,2,3,4 # specify the dynamical schemes to use.
>> INFO: # -1 is the one used by the sample.
>> INFO: # > 0 correspond to options of dynamical_scale_choice of the run_card.
>> INFO: --pdf=errorset # specify the pdfs to use for pdf variation. (see below)
>> INFO: --together=mur,muf,dyn # which parameter should we vary together to have all uncorrelated combination of the variations
>> INFO: --from_card # use the information from the run_card (LO only).
>> INFO:
>> INFO: Allowed value for the pdf options:
>> INFO: central : Do not perform any pdf variation
>> INFO: errorset : runs over the errorset
>> INFO: 244800 : ...

Revision history for this message
Eleni Vryonidou (evryonidou) wrote :
Download full text (303.0 KiB)

Hi,

ok that works now.

At NLO if I generate events with the default pdf set (nn23nlo) it crashes with the following error:

PROCNLO_loop_sm_0>systematics run_02
INFO: Running Systematic computation
INFO: Idle: 1, Running: 3, Completed: 0 [ current time: 17h12 ]
WARNING: program /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python /Users/evryonidou/Desktop/python_syscalc/PROCNLO_loop_sm_0/bin/internal/systematics.py events.lhe.gz ./tmp_0_events.lhe.gz --start_event=0 --stop_event=2500 --result=./log_sys_0.txt --lhapdf_config=lhapdf-config launch ends with non zero status: 1. Stop all computation
WARNING: program /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python /Users/evryonidou/Desktop/python_syscalc/PROCNLO_loop_sm_0/bin/internal/systematics.py events.lhe.gz ./tmp_1_events.lhe.gz --start_event=2500 --stop_event=5000 --result=./log_sys_1.txt --lhapdf_config=lhapdf-config launch ends with non zero status: 1. Stop all computation
Command "systematics run_02" interrupted with error:
Exception : program /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python /Users/evryonidou/Desktop/python_syscalc/PROCNLO_loop_sm_0/bin/internal/systematics.py events.lhe.gz ./tmp_0_events.lhe.gz --start_event=0 --stop_event=2500 --result=./log_sys_0.txt --lhapdf_config=lhapdf-config launch ends with non zero status: 1. Stop all computation

If I generate events with lhapdf then it works fine.

Cheers,

Eleni

> On 22 Aug 2016, at 21:00, Olivier Mattelaer <email address hidden> wrote:
>
> Thanks to have spot this.
>
> It should be fix now.
>
> Cheers,
>
> Olivier
>> On Aug 22, 2016, at 18:30, Eleni Vryonidou <email address hidden> wrote:
>>
>> Hi Olivier,
>>
>> I tried getting a fresh branch of python_syscalc but trying to run fails with this error:
>>
>> ImportError : No module named various.systematics
>>
>> And in the log file:
>>
>> File "/Users/evryonidou/Desktop/python_syscalc/check/bin/internal/common_run_interface.py", line 1336, in do_systematics
>> import internal.various.systematics as systematics
>> ImportError: No module named various.systematics
>>
>> So I couldn’t go further with any other checks… Do you have any idea what this problem is?
>>
>> Cheers,
>>
>> Eleni
>>
>>
>>> On 12 Aug 2016, at 01:55, Olivier Mattelaer <email address hidden> wrote:
>>>
>>> Olivier Mattelaer has proposed merging lp:~maddevelopers/mg5amcnlo/python_syscalc into lp:~maddevelopers/mg5amcnlo/2.5.0.
>>>
>>> Requested reviews:
>>> Eleni Vryonidou (evryonidou)
>>> Rikkert Frederix (frederix)
>>> Valentin Hirschi (valentin-hirschi)
>>>
>>> For more details, see:
>>> https://code.launchpad.net/~maddevelopers/mg5amcnlo/python_syscalc/+merge/302735
>>>
>>> This version allows to compute systematics error band on both LO and NLO sample.
>>>
>>> For LO code, this is run automatically if 'use_syst' is set on True in the run_card.
>>> For NLO code, this need to be called manually via the command 'systematics RUN_XX OPTIONS'
>>> The sample need to be generated with the options 'store_...

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :
Download full text (304.9 KiB)

Hi,

This is actually a bug of the lhapdf nn23nlo set.

*** skip this if you do not care to know what the bug is ***

More in details, the version from MG5 is not the same as the one from lhapdf.
Turns out that the one from MG5 is the correct one and that they have to update their set on lhapdf.
Indeed in lhapdf, the central set was generated with a fit for the options ‘always positive’ but the error set was fitted for the options ’can be negative’.
so the set is inconsistent. In MG5aMC, the central set is ‘can be negative’ which is the central value of the associated error set.
The LHAPDF author/NNPDF author are aware of this, but I do not know when and how this error will be solved. (The bug was actually spotted due to this project).
Since this will pass by an update of the pdf, it is likely that people will not perform the update of the set for a long time…

*** end of the bug description ***

I just think of a new work-around which is not perfect but good enough
1) if the central pdf is zero, then use the wgt from the event to get the pdf value.
2) if the pdf is non zero, use it.
in debug mode, this the second will need to a crash since the code will realize that a mismatch happens.
I have updated the code such that in production mode, the test/crash does not happen.

Cheers,

Olivier

PS: I have made a test from re-computing the central pdf from the errorset, and this slow down the code by huge factor (20 times slower) and provide the same result as the above.
PPS: if you want to test, please run in production mode with python -O before the executable.

> On Aug 23, 2016, at 16:24, Eleni Vryonidou <email address hidden> wrote:
>
> Hi,
>
> ok that works now.
>
> At NLO if I generate events with the default pdf set (nn23nlo) it crashes with the following error:
>
> PROCNLO_loop_sm_0>systematics run_02
> INFO: Running Systematic computation
> INFO: Idle: 1, Running: 3, Completed: 0 [ current time: 17h12 ]
> WARNING: program /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python /Users/evryonidou/Desktop/python_syscalc/PROCNLO_loop_sm_0/bin/internal/systematics.py events.lhe.gz ./tmp_0_events.lhe.gz --start_event=0 --stop_event=2500 --result=./log_sys_0.txt --lhapdf_config=lhapdf-config launch ends with non zero status: 1. Stop all computation
> WARNING: program /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python /Users/evryonidou/Desktop/python_syscalc/PROCNLO_loop_sm_0/bin/internal/systematics.py events.lhe.gz ./tmp_1_events.lhe.gz --start_event=2500 --stop_event=5000 --result=./log_sys_1.txt --lhapdf_config=lhapdf-config launch ends with non zero status: 1. Stop all computation
> Command "systematics run_02" interrupted with error:
> Exception : program /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python /Users/evryonidou/Desktop/python_syscalc/PROCNLO_loop_sm_0/bin/internal/systematics.py events.lhe.gz ./tmp_0_events.lhe.gz --start_event=0 --stop_event=2500 --result=./log_sys_0.txt --lhapdf_config=lhapdf-config launch ends with non zero status: 1. Stop all computation
>
> If I...

300. By Olivier Mattelaer

put in place a nice workaround in presence of the nnpdf23 bug

301. By Olivier Mattelaer

add security to check that the card are consistent with the systematic computation

302. By Olivier Mattelaer

fixing a bug in the reweight module (incorrect relative path)

303. By Olivier Mattelaer

remove a print comment

Revision history for this message
Eleni Vryonidou (evryonidou) :
review: Approve
Revision history for this message
Rikkert Frederix (frederix) wrote :

Hi Olivier,

Ok. I finally had some time to look into this branch. I haven't really tested anything yet, but looking through the changes made in this branch, I noticed that there might be a mistake related to the possible changes of the dynamical scale setting 'dyn'. In particular, it looks like you simply recompute if from the momenta as given in the event file. This is not correct, because this gives different scales to the (MC) subtraction terms in the S and H events, even if those subtraction terms were computed with exactly the same kinematics.

What we do in normal running of the code is the following:

n-body kinematics:
- Born
- Virtual
- (Integrated) FKS Subtraction terms

(n+1)-body kinematics:
- MC subtraction terms (in S and H events)
- Real-emission

See also the calls to 'set_alphaS' in driver_mintMC where the scales are either set using n-body kinematics ('call set_alphaS(p1_cnt(0,1,0))') or (n+1)-body kinematics ('call set_alphaS(p)'), with the subsequent calls to the matrix elements just after those.

I think this needs to be changed, even though in practice this difference is numerically usually small. But to get it 100% correct these changes are needed.

Cheers,
Rik

review: Approve
Revision history for this message
Rikkert Frederix (frederix) :
review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Template/LO/Cards/run_card.dat'
--- Template/LO/Cards/run_card.dat 2015-08-11 00:35:53 +0000
+++ Template/LO/Cards/run_card.dat 2016-08-24 22:15:21 +0000
@@ -279,5 +279,5 @@
279%(sys_alpsfact)s = sys_alpsfact # \alpha_s emission scale factors279%(sys_alpsfact)s = sys_alpsfact # \alpha_s emission scale factors
280%(sys_matchscale)s = sys_matchscale # variation of merging scale280%(sys_matchscale)s = sys_matchscale # variation of merging scale
281# PDF sets and number of members (0 or none for all members).281# PDF sets and number of members (0 or none for all members).
282%(sys_pdf)s = sys_pdf # matching scales282%(sys_pdf)s = sys_pdf # separate by && if more than one set.
283# MSTW2008nlo68cl.LHgrid 1 = sys_pdf283# MSTW2008nlo68cl.LHgrid 1 = sys_pdf
284284
=== modified file 'Template/LO/SubProcesses/reweight.f'
--- Template/LO/SubProcesses/reweight.f 2016-06-07 09:33:55 +0000
+++ Template/LO/SubProcesses/reweight.f 2016-08-24 22:15:21 +0000
@@ -994,21 +994,21 @@
994 pt2ijcl(nexternal-2)=q2fact(1)994 pt2ijcl(nexternal-2)=q2fact(1)
995 if(nexternal.gt.3) pt2ijcl(nexternal-3)=q2fact(1)995 if(nexternal.gt.3) pt2ijcl(nexternal-3)=q2fact(1)
996 else996 else
997 q2fact(1)=pt2ijcl(nexternal-2)997 q2fact(1)=scalefact**2*pt2ijcl(nexternal-2)
998 q2fact(2)=q2fact(1)998 q2fact(2)=scalefact**2*q2fact(1)
999 endif999 endif
1000 elseif(jcentral(1).eq.0)then1000 elseif(jcentral(1).eq.0)then
1001 q2fact(1) = pt2ijcl(jfirst(1))1001 q2fact(1) = scalefact**2*pt2ijcl(jfirst(1))
1002 elseif(jcentral(2).eq.0)then1002 elseif(jcentral(2).eq.0)then
1003 q2fact(2) = pt2ijcl(jfirst(2))1003 q2fact(2) = scalefact**2*pt2ijcl(jfirst(2))
1004 elseif(ickkw.eq.2.or.(pdfwgt.and.ickkw.gt.0))then1004 elseif(ickkw.eq.2.or.(pdfwgt.and.ickkw.gt.0))then
1005c Total pdf weight is f1(x1,pt2E)*fj(x1*z,Q)/fj(x1*z,pt2E)1005c Total pdf weight is f1(x1,pt2E)*fj(x1*z,Q)/fj(x1*z,pt2E)
1006c f1(x1,pt2E) is given by DSIG, just need to set scale.1006c f1(x1,pt2E) is given by DSIG, just need to set scale.
1007c Use the minimum scale found for fact scale in ME1007c Use the minimum scale found for fact scale in ME
1008 if(jlast(1).gt.0.and.jfirst(1).le.jlast(1))1008 if(jlast(1).gt.0.and.jfirst(1).le.jlast(1))
1009 $ q2fact(1)=min(pt2ijcl(jfirst(1)),q2fact(1))1009 $ q2fact(1)=scalefact**2*min(pt2ijcl(jfirst(1)),q2fact(1))
1010 if(jlast(2).gt.0.and.jfirst(2).le.jlast(2))1010 if(jlast(2).gt.0.and.jfirst(2).le.jlast(2))
1011 $ q2fact(2)=min(pt2ijcl(jfirst(2)),q2fact(2))1011 $ q2fact(2)=scalefact**2*min(pt2ijcl(jfirst(2)),q2fact(2))
1012 endif1012 endif
10131013
1014c Check that factorization scale is >= 2 GeV1014c Check that factorization scale is >= 2 GeV
10151015
=== modified file 'UpdateNotes.txt'
--- UpdateNotes.txt 2016-08-17 19:36:40 +0000
+++ UpdateNotes.txt 2016-08-24 22:15:21 +0000
@@ -1,5 +1,6 @@
1Update notes for MadGraph5_aMC@NLO (in reverse time order)1Update notes for MadGraph5_aMC@NLO (in reverse time order)
22
3<<<<<<< TREE
32.5.042.5.0
4 OM: Modify the structure of the output format such that all the internal format have the same structure5 OM: Modify the structure of the output format such that all the internal format have the same structure
5 OM: Adding the Plugin directory. Three kind of plugin are currently supported6 OM: Adding the Plugin directory. Three kind of plugin are currently supported
@@ -15,6 +16,20 @@
15 OM: add the check that the param_card is compatible with the model restriction.16 OM: add the check that the param_card is compatible with the model restriction.
16 OM+VH: 17 OM+VH:
17 18
19=======
20
21X.X.X (xx/xx/xx)
22 OM: NLO/LO Re-weighting works in multi-core
23 OM: Introduces a new function for LO/NLO interface "systematics"
24 This function allows to compute systematics uncertainty from the event sample
25 It requires the event sample to have been generated with
26 - use_syst = T (for LO sample)
27 - store_reweight_info = T (for NLO sample)
28 At LO the code is run automatically if use_syst=T (but if SysCalc is installed)
29 OM: Fix a bug in the reweight_card where relative path was not understood from the local directory
30 where the program was runned by the user.
31
32>>>>>>> MERGE-SOURCE
182.4.3 (01/08/16)332.4.3 (01/08/16)
19 OM: Reduce the amount of log file/output generated for LO run (output can use up to three times less output).34 OM: Reduce the amount of log file/output generated for LO run (output can use up to three times less output).
20 OM: For the LO combination of events (unweighting) pass to the method previously used for loop-induced.35 OM: For the LO combination of events (unweighting) pass to the method previously used for loop-induced.
2136
=== modified file 'VERSION'
--- VERSION 2016-08-03 13:42:53 +0000
+++ VERSION 2016-08-24 22:15:21 +0000
@@ -1,5 +1,11 @@
1<<<<<<< TREE
1version = 2.5.0.alpha2version = 2.5.0.alpha
2date = 2016-08-013date = 2016-08-01
4=======
5version = new_sys
6date = 2016-08-08
7
8>>>>>>> MERGE-SOURCE
39
410
511
612
=== modified file 'madgraph/interface/amcatnlo_run_interface.py'
--- madgraph/interface/amcatnlo_run_interface.py 2016-08-17 16:25:19 +0000
+++ madgraph/interface/amcatnlo_run_interface.py 2016-08-24 22:15:21 +0000
@@ -3297,98 +3297,6 @@
3297 self.update_status('Run complete', level='shower', update_results=True)3297 self.update_status('Run complete', level='shower', update_results=True)
32983298
32993299
3300 ############################################################################
3301 def set_run_name(self, name, tag=None, level='parton', reload_card=False):
3302 """define the run name, the run_tag, the banner and the results."""
3303
3304 # when are we force to change the tag new_run:previous run requiring changes
3305 upgrade_tag = {'parton': ['parton','pythia','pgs','delphes','shower'],
3306 'pythia': ['pythia','pgs','delphes'],
3307 'shower': ['shower'],
3308 'pgs': ['pgs'],
3309 'delphes':['delphes'],
3310 'plot':[]}
3311
3312
3313
3314 if name == self.run_name:
3315 if reload_card:
3316 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3317 self.run_card = banner_mod.RunCardNLO(run_card)
3318
3319 #check if we need to change the tag
3320 if tag:
3321 self.run_card['run_tag'] = tag
3322 self.run_tag = tag
3323 self.results.add_run(self.run_name, self.run_card)
3324 else:
3325 for tag in upgrade_tag[level]:
3326 if getattr(self.results[self.run_name][-1], tag):
3327 tag = self.get_available_tag()
3328 self.run_card['run_tag'] = tag
3329 self.run_tag = tag
3330 self.results.add_run(self.run_name, self.run_card)
3331 break
3332 return # Nothing to do anymore
3333
3334 # save/clean previous run
3335 if self.run_name:
3336 self.store_result()
3337 # store new name
3338 self.run_name = name
3339
3340 # Read run_card
3341 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3342 self.run_card = banner_mod.RunCardNLO(run_card)
3343
3344 new_tag = False
3345 # First call for this run -> set the banner
3346 self.banner = banner_mod.recover_banner(self.results, level, self.run_name, tag)
3347 if tag:
3348 self.run_card['run_tag'] = tag
3349 new_tag = True
3350 elif not self.run_name in self.results and level =='parton':
3351 pass # No results yet, so current tag is fine
3352 elif not self.run_name in self.results:
3353 #This is only for case when you want to trick the interface
3354 logger.warning('Trying to run data on unknown run.')
3355 self.results.add_run(name, self.run_card)
3356 self.results.update('add run %s' % name, 'all', makehtml=True)
3357 else:
3358 for tag in upgrade_tag[level]:
3359
3360 if getattr(self.results[self.run_name][-1], tag):
3361 # LEVEL is already define in the last tag -> need to switch tag
3362 tag = self.get_available_tag()
3363 self.run_card['run_tag'] = tag
3364 new_tag = True
3365 break
3366 if not new_tag:
3367 # We can add the results to the current run
3368 tag = self.results[self.run_name][-1]['tag']
3369 self.run_card['run_tag'] = tag # ensure that run_tag is correct
3370
3371
3372 if name in self.results and not new_tag:
3373 self.results.def_current(self.run_name)
3374 else:
3375 self.results.add_run(self.run_name, self.run_card)
3376
3377 self.run_tag = self.run_card['run_tag']
3378
3379 # Return the tag of the previous run having the required data for this
3380 # tag/run to working wel.
3381 if level == 'parton':
3382 return
3383 elif level == 'pythia':
3384 return self.results[self.run_name][0]['tag']
3385 else:
3386 for i in range(-1,-len(self.results[self.run_name])-1,-1):
3387 tagRun = self.results[self.run_name][i]
3388 if tagRun.pythia:
3389 return tagRun['tag']
3390
3391
3392 def store_result(self):3300 def store_result(self):
3393 """ tar the pythia results. This is done when we are quite sure that 3301 """ tar the pythia results. This is done when we are quite sure that
3394 the pythia output will not be use anymore """3302 the pythia output will not be use anymore """
@@ -4928,9 +4836,9 @@
4928 if '--web' in args:4836 if '--web' in args:
4929 i = args.index('--web') 4837 i = args.index('--web')
4930 args.pop(i) 4838 args.pop(i)
4931 cmd_line = aMCatNLOCmd(force_run=True)4839 cmd_line = aMCatNLOCmd(me_dir=os.path.dirname(root_path),force_run=True)
4932 else:4840 else:
4933 cmd_line = aMCatNLOCmdShell(force_run=True)4841 cmd_line = aMCatNLOCmdShell(me_dir=os.path.dirname(root_path),force_run=True)
49344842
4935 if not hasattr(cmd_line, 'do_%s' % args[0]):4843 if not hasattr(cmd_line, 'do_%s' % args[0]):
4936 if parser_error:4844 if parser_error:
49374845
=== modified file 'madgraph/interface/common_run_interface.py'
--- madgraph/interface/common_run_interface.py 2016-08-17 16:25:19 +0000
+++ madgraph/interface/common_run_interface.py 2016-08-24 22:15:21 +0000
@@ -68,6 +68,7 @@
68 import internal.files as files68 import internal.files as files
69 import internal.save_load_object as save_load_object69 import internal.save_load_object as save_load_object
70 import internal.gen_crossxhtml as gen_crossxhtml70 import internal.gen_crossxhtml as gen_crossxhtml
71 import internal.lhe_parser as lhe_parser
71 from internal import InvalidCmd, MadGraph5Error72 from internal import InvalidCmd, MadGraph5Error
72 MADEVENT=True 73 MADEVENT=True
73else:74else:
@@ -78,6 +79,7 @@
78 import madgraph.various.misc as misc79 import madgraph.various.misc as misc
79 import madgraph.iolibs.files as files80 import madgraph.iolibs.files as files
80 import madgraph.various.cluster as cluster81 import madgraph.various.cluster as cluster
82 import madgraph.various.lhe_parser as lhe_parser
81 import madgraph.iolibs.save_load_object as save_load_object83 import madgraph.iolibs.save_load_object as save_load_object
82 import madgraph.madevent.gen_crossxhtml as gen_crossxhtml84 import madgraph.madevent.gen_crossxhtml as gen_crossxhtml
83 import models.check_param_card as check_param_card85 import models.check_param_card as check_param_card
@@ -450,7 +452,6 @@
450 """return the path to the output events452 """return the path to the output events
451 """453 """
452454
453
454 if self.mode == 'madevent':455 if self.mode == 'madevent':
455 possible_path = [456 possible_path = [
456 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe.gz'),457 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe.gz'),
@@ -465,7 +466,10 @@
465 correct_path = path466 correct_path = path
466 break467 break
467 else:468 else:
468 raise self.InvalidCmd('No events file corresponding to %s run. ' % run_name)469 if os.path.exists(run_name):
470 correct_path = run_name
471 else:
472 raise self.InvalidCmd('No events file corresponding to %s run. ' % run_name)
469 return correct_path473 return correct_path
470474
471475
@@ -619,6 +623,101 @@
619623
620 return args624 return args
621625
626 ############################################################################
627 def set_run_name(self, name, tag=None, level='parton', reload_card=False,
628 allow_new_tag=True):
629 """define the run name, the run_tag, the banner and the results."""
630
631 # when are we force to change the tag new_run:previous run requiring changes
632 upgrade_tag = {'parton': ['parton','pythia','pgs','delphes'],
633 'pythia': ['pythia','pgs','delphes'],
634 'pgs': ['pgs'],
635 'delphes':['delphes'],
636 'plot':[],
637 'syscalc':[]}
638
639
640
641 if name == self.run_name:
642 if reload_card:
643 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
644 self.run_card = banner_mod.RunCard(run_card)
645
646 #check if we need to change the tag
647 if tag:
648 self.run_card['run_tag'] = tag
649 self.run_tag = tag
650 self.results.add_run(self.run_name, self.run_card)
651 else:
652 for tag in upgrade_tag[level]:
653 if getattr(self.results[self.run_name][-1], tag):
654 tag = self.get_available_tag()
655 self.run_card['run_tag'] = tag
656 self.run_tag = tag
657 self.results.add_run(self.run_name, self.run_card)
658 break
659 return # Nothing to do anymore
660
661 # save/clean previous run
662 if self.run_name:
663 self.store_result()
664 # store new name
665 self.run_name = name
666
667 new_tag = False
668 # First call for this run -> set the banner
669 self.banner = banner_mod.recover_banner(self.results, level, name)
670 if 'mgruncard' in self.banner:
671 self.run_card = self.banner.charge_card('run_card')
672 else:
673 # Read run_card
674 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
675 self.run_card = banner_mod.RunCard(run_card)
676
677 if tag:
678 self.run_card['run_tag'] = tag
679 new_tag = True
680 elif not self.run_name in self.results and level =='parton':
681 pass # No results yet, so current tag is fine
682 elif not self.run_name in self.results:
683 #This is only for case when you want to trick the interface
684 logger.warning('Trying to run data on unknown run.')
685 self.results.add_run(name, self.run_card)
686 self.results.update('add run %s' % name, 'all', makehtml=False)
687 else:
688 for tag in upgrade_tag[level]:
689
690 if getattr(self.results[self.run_name][-1], tag):
691 # LEVEL is already define in the last tag -> need to switch tag
692 tag = self.get_available_tag()
693 self.run_card['run_tag'] = tag
694 new_tag = True
695 break
696 if not new_tag:
697 # We can add the results to the current run
698 tag = self.results[self.run_name][-1]['tag']
699 self.run_card['run_tag'] = tag # ensure that run_tag is correct
700
701 if allow_new_tag and (name in self.results and not new_tag):
702 self.results.def_current(self.run_name)
703 else:
704 self.results.add_run(self.run_name, self.run_card)
705
706 self.run_tag = self.run_card['run_tag']
707
708 # Return the tag of the previous run having the required data for this
709 # tag/run to working wel.
710 if level == 'parton':
711 return
712 elif level == 'pythia':
713 return self.results[self.run_name][0]['tag']
714 else:
715 for i in range(-1,-len(self.results[self.run_name])-1,-1):
716 tagRun = self.results[self.run_name][i]
717 if tagRun.pythia:
718 return tagRun['tag']
719
720
622 @misc.multiple_try(nb_try=5, sleep=2)721 @misc.multiple_try(nb_try=5, sleep=2)
623 def load_results_db(self):722 def load_results_db(self):
624 """load the current results status"""723 """load the current results status"""
@@ -1087,7 +1186,270 @@
1087 """Dummy routine, to be overwritten by daughter classes"""1186 """Dummy routine, to be overwritten by daughter classes"""
10881187
1089 pass1188 pass
1090 1189
1190 ############################################################################
1191 def help_systematics(self):
1192 """help for systematics command"""
1193 logger.info("syntax: systematics RUN_NAME [OUTPUT] [options]",'$MG:color:BLACK')
1194 logger.info("-- Run the systematics run on the run_name run.")
1195 logger.info(" RUN_NAME can be a path to a lhef file.")
1196 logger.info(" OUTPUT can be the path to the output lhe file. we overwritte the input file otherwise")
1197 logger.info("")
1198 logger.info("options: (value written are default)", '$MG:color:BLACK')
1199 logger.info("")
1200 logger.info(" --mur=0.5,1,2 # specify the values for renormalisation scale variation")
1201 logger.info(" --muf=0.5,1,2 # specify the values for factorisation scale variation")
1202 logger.info(" --alps=1 # specify the values for MLM emission scale variation")
1203 logger.info(" --dyn=-1,1,2,3,4 # specify the dynamical schemes to use.")
1204 logger.info(" # -1 is the one used by the sample.")
1205 logger.info(" # > 0 correspond to options of dynamical_scale_choice of the run_card.")
1206 logger.info(" --pdf=errorset # specify the pdfs to use for pdf variation. (see below)")
1207 logger.info(" --together=mur,muf,dyn # lists the parameter that must be varied simultaneously so as to ")
1208 logger.info(" # compute the weights for all combinations of their variations.")
1209 logger.info(" --from_card # use the information from the run_card (LO only).")
1210 logger.info("")
1211 logger.info(" Allowed value for the pdf options:", '$MG:color:BLACK')
1212 logger.info(" central : Do not perform any pdf variation" )
1213 logger.info(" errorset : runs over the errorset")
1214 logger.info(" 244800 : runs over the associated set and his errorset")
1215 logger.info(" 244800@0 : runs over the associated set ONLY")
1216# logger.info(" 244800@X : runs over the Xth set of the associated error set")
1217 logger.info(" CT10 : runs over the associated set and his errorset")
1218 logger.info(" CT10@0 : runs over the associated set ONLY")
1219 logger.info(" CT10@X : runs over the Xth set of the associated error set")
1220 logger.info(" XX,YY,ZZ : runs over the sets for XX,YY,ZZ (those three follows above syntax)")
1221
1222 def complete_systematics(self, text, line, begidx, endidx):
1223 """auto completion for the systematics command"""
1224
1225 args = self.split_arg(line[0:begidx], error=False)
1226 options = ['--mur=', '--muf=', '--pdf=', '--dyn=','--alps=','--together=','--from_card ']
1227
1228 if len(args) == 1 and os.path.sep not in text:
1229 #return valid run_name
1230 data = misc.glob(pjoin('*','*events.lhe*'), pjoin(self.me_dir, 'Events'))
1231 data = [n.rsplit('/',2)[1] for n in data]
1232 return self.list_completion(text, data, line)
1233 elif len(args)==1:
1234 #logger.warning('1args')
1235 return self.path_completion(text,
1236 os.path.join('.',*[a for a in args \
1237 if a.endswith(os.path.sep)]))
1238 elif len(args)==2 and os.path.sep in args[1]:
1239 #logger.warning('2args %s', args[1])
1240 return self.path_completion(text, '.')
1241
1242 elif not line.endswith(tuple(options)):
1243 return self.list_completion(text, options)
1244
1245
1246 ############################################################################
1247 def do_systematics(self, line):
1248 """ syntax is 'systematics [INPUT [OUTPUT]] OPTIONS'
1249 --mur=0.5,1,2
1250 --muf=0.5,1,2
1251 --alps=1
1252 --dyn=-1
1253 --together=mur,muf #can be repeated
1254
1255 #special options
1256 --from_card=
1257 """
1258
1259 lhapdf = misc.import_python_lhapdf(self.options['lhapdf'])
1260 if not lhapdf:
1261 logger.info('can not run systematics since can not link python to lhapdf')
1262 return
1263
1264 self.update_status('Running Systematic computation', level='parton')
1265 args = self.split_arg(line)
1266 #split arguments and option
1267 opts= []
1268 args = [a for a in args if not a.startswith('-') or opts.append(a)]
1269
1270 #check sanity of options
1271 if any(not o.startswith(('--mur=', '--muf=', '--alps=','--dyn=','--together=','--from_card','--pdf='))
1272 for o in opts):
1273 raise self.InvalidCmd, "command systematics called with invalid option syntax. Please retry."
1274
1275 # check that we have define the input
1276 if len(args) == 0:
1277 if self.run_name:
1278 args[0] = self.run_name
1279 else:
1280 raise self.InvalidCmd, 'no default run. Please specify the run_name'
1281
1282 # always pass to a path + get the event size
1283 result_file= sys.stdout
1284 if not os.path.sep in args[0]:
1285 path = [pjoin(self.me_dir, 'Events', args[0], 'unweighted_events.lhe.gz'),
1286 pjoin(self.me_dir, 'Events', args[0], 'unweighted_events.lhe'),
1287 pjoin(self.me_dir, 'Events', args[0], 'events.lhe.gz'),
1288 pjoin(self.me_dir, 'Events', args[0], 'events.lhe')]
1289
1290 for p in path:
1291 if os.path.exists(p):
1292 nb_event = self.results[args[0]].get_current_info()['nb_event']
1293
1294
1295 if self.run_name != args[0]:
1296 tag = self.results[args[0]].tags[0]
1297 self.set_run_name(args[0], tag,'parton', False)
1298 result_file = open(pjoin(self.me_dir,'Events', self.run_name, 'parton_systematics.log'),'w')
1299 args[0] = p
1300 break
1301 else:
1302 raise self.InvalidCmd, 'Invalid run name. Please retry'
1303 elif self.options['nb_core'] != 1:
1304 lhe = lhe_parser.EventFile(args)
1305 nb_event = len(lhe)
1306 lhe.close()
1307
1308 input = args[0]
1309 if len(args)>1:
1310 output = pjoin(os.getcwd(),args[1])
1311 else:
1312 output = input
1313
1314 lhaid = [self.run_card.get_lhapdf_id()]
1315 if 'store_rwgt_info' in self.run_card and not self.run_card['store_rwgt_info']:
1316 raise self.InvalidCmd, "The events was not generated with store_rwgt_info=True. Can not evaluate systematics error on this event file."
1317 elif 'use_syst' in self.run_card and not self.run_card['use_syst']:
1318 raise self.InvalidCmd, "The events was not generated with use_syst=True. Can not evaluate systematics error on this event file."
1319
1320 try:
1321 pdfsets_dir = self.get_lhapdf_pdfsetsdir()
1322 except Exception, error:
1323 logger.debug(str(error))
1324 logger.warning('Systematic computation requires lhapdf to run. Bypass Systematics')
1325 return
1326
1327 if '--from_card' in opts:
1328 opts.remove('--from_card')
1329 opts.append('--from_card=internal')
1330
1331 # Check that all pdfset are correctly installed
1332 if 'sys_pdf' in self.run_card:
1333 sys_pdf = self.run_card['sys_pdf'].split('&&')
1334 lhaid += [l.split()[0] for l in sys_pdf]
1335
1336 else:
1337 #check that all p
1338 pdf = [a[6:] for a in opts if a.startswith('--pdf=')]
1339 lhaid += [t.split('@')[0] for p in pdf for t in p.split(',')
1340 if t not in ['errorset', 'central']]
1341
1342 # Copy all the relevant PDF sets
1343 [self.copy_lhapdf_set([onelha], pdfsets_dir) for onelha in lhaid]
1344
1345
1346 if self.options['run_mode'] ==2:
1347 nb_submit = min(self.options['nb_core'], nb_event//2500)
1348 elif self.options['run_mode'] ==1:
1349 nb_submit = min(self.options['cluster_size'], nb_event//25000)
1350 else:
1351 nb_submit =1
1352
1353 if MADEVENT:
1354 import internal.systematics as systematics
1355 else:
1356 import madgraph.various.systematics as systematics
1357
1358 #one core:
1359 if nb_submit in [0,1]:
1360 systematics.call_systematics([input, output] + opts,
1361 log=lambda x: logger.info(str(x)),
1362 result=result_file
1363 )
1364
1365 elif self.options['run_mode'] in [1,2]:
1366 event_per_job = nb_event // nb_submit
1367 nb_job_with_plus_one = nb_event % nb_submit
1368 start_event, stop_event = 0,0
1369 for i in range(nb_submit):
1370 #computing start/stop event
1371 event_requested = event_per_job
1372 if i < nb_job_with_plus_one:
1373 event_requested += 1
1374 start_event = stop_event
1375 stop_event = start_event + event_requested
1376
1377 prog = sys.executable
1378 input_files = [os.path.basename(input)]
1379 output_files = ['./tmp_%s_%s' % (i, os.path.basename(output)),
1380 './log_sys_%s.txt' % (i)]
1381 argument = []
1382 if not __debug__:
1383 argument.append('-O')
1384 argument += [pjoin(self.me_dir, 'bin', 'internal', 'systematics.py'),
1385 input_files[0], output_files[0]] + opts +\
1386 ['--start_event=%i' % start_event,
1387 '--stop_event=%i' %stop_event,
1388 '--result=./log_sys_%s.txt' %i,
1389 '--lhapdf_config=%s' % self.options['lhapdf']]
1390 required_output = output_files
1391 self.cluster.cluster_submit(prog, argument,
1392 input_files=input_files,
1393 output_files=output_files,
1394 cwd=os.path.dirname(output),
1395 required_output=required_output,
1396 stdout='/dev/null'
1397 )
1398 starttime = time.time()
1399 update_status = lambda idle, run, finish: \
1400 self.update_status((idle, run, finish, 'running systematics'), level=None,
1401 force=False, starttime=starttime)
1402
1403 self.cluster.wait(os.path.dirname(output), update_status, update_first=update_status)
1404
1405 #collect the data
1406 all_cross = []
1407 for i in range(nb_submit):
1408 pos=0
1409 for line in open(pjoin(os.path.dirname(output), 'log_sys_%s.txt'%i)):
1410 if line.startswith('#'):
1411 continue
1412 split = line.split()
1413 if len(split) in [0,1]:
1414 continue
1415 key = tuple(float(x) for x in split[:-1])
1416 cross= float(split[-1])
1417 if 'event_norm' in self.run_card and \
1418 self.run_card['event_norm'] in ['average', 'unity']:
1419 cross *= (event_per_job+1 if i <nb_job_with_plus_one else event_per_job)
1420 if len(all_cross) > pos:
1421 all_cross[pos] += cross
1422 else:
1423 all_cross.append(cross)
1424 pos+=1
1425
1426 if 'event_norm' in self.run_card and \
1427 self.run_card['event_norm'] in ['unity']:
1428 all_cross= [cross/nb_event for cross in all_cross]
1429
1430 sys_obj = systematics.call_systematics([input, None] + opts,
1431 log=lambda x: logger.info(str(x)),
1432 result=result_file,
1433 running=False
1434 )
1435 sys_obj.print_cross_sections(all_cross, nb_event, result_file)
1436
1437 #concatenate the output file
1438 subprocess.call(['cat']+\
1439 ['./tmp_%s_%s' % (i, os.path.basename(output)) for i in range(nb_submit)],
1440 stdout=open(output,'w'),
1441 cwd=os.path.dirname(output))
1442 for i in range(nb_submit):
1443 os.remove('%s/tmp_%s_%s' %(os.path.dirname(output),i,os.path.basename(output)))
1444 # os.remove('%s/log_sys_%s.txt' % (os.path.dirname(output),i))
1445
1446
1447
1448
1449
1450 self.update_status('End of systematics computation', level='parton', makehtml=False)
1451
1452
1091 ############################################################################1453 ############################################################################
1092 def do_reweight(self, line):1454 def do_reweight(self, line):
1093 """ syntax is "reweight RUN_NAME"1455 """ syntax is "reweight RUN_NAME"
@@ -1096,9 +1458,50 @@
1096 cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Reweight1458 cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Reweight
1097 """1459 """
1098 1460
1461 #### Utility function
1462 def check_multicore(self):
1463 """ determine if the cards are save for multicore use"""
1464 card = pjoin(self.me_dir, 'Cards', 'reweight_card.dat')
1465
1466 multicore = True
1467 if self.options['run_mode'] in [0,1]:
1468 multicore = False
1469
1470 lines = [l.strip() for l in open(card) if not l.strip().startswith('#')]
1471 while lines and not lines[0].startswith('launch'):
1472 line = lines.pop(0)
1473 # if not standard output mode forbid multicore mode
1474 if line.startswith('change') and line[6:].strip().startswith('output'):
1475 return False
1476 if line.startswith('change') and line[6:].strip().startswith('multicore'):
1477 split_line = line.split()
1478 if len(split_line) > 2:
1479 multicore = bool(split_line[2])
1480 # we have reached the first launch in the card ensure that no output change
1481 #are done after that point.
1482 lines = [line[6:].strip() for line in lines if line.startswith('change')]
1483 for line in lines:
1484 if line.startswith(('process','model','output', 'rwgt_dir')):
1485 return False
1486 elif line.startswith('multicore'):
1487 split_line = line.split()
1488 if len(split_line) > 1:
1489 multicore = bool(split_line[1])
1490
1491 return multicore
1492
1493
1494
1099 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'reweight_card.dat')):1495 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'reweight_card.dat')):
1100 return1496 return
1101 1497 # option for multicore to avoid that all of them create the same directory
1498 if '--multicore=create' in line:
1499 multicore='create'
1500 elif '--multicore=wait' in line:
1501 multicore='wait'
1502 else:
1503 multicore=False
1504
1102 # Check that MG5 directory is present .1505 # Check that MG5 directory is present .
1103 if MADEVENT and not self.options['mg5_path']:1506 if MADEVENT and not self.options['mg5_path']:
1104 raise self.InvalidCmd, '''The module reweight requires that MG5 is installed on the system.1507 raise self.InvalidCmd, '''The module reweight requires that MG5 is installed on the system.
@@ -1125,6 +1528,10 @@
1125 if self.run_name and self.results.current and self.results.current['cross'] == 0:1528 if self.run_name and self.results.current and self.results.current['cross'] == 0:
1126 self.results.delete_run(self.run_name, self.run_tag)1529 self.results.delete_run(self.run_name, self.run_tag)
1127 self.results.save()1530 self.results.save()
1531 # ensure that the run_card is present
1532 if not hasattr(self, 'run_card'):
1533 self.run_card = banner_mod.RunCard(pjoin(self.me_dir, 'Cards', 'run_card.dat'))
1534
1128 # we want to run this in a separate shell to avoid hard f2py crash1535 # we want to run this in a separate shell to avoid hard f2py crash
1129 command = [sys.executable]1536 command = [sys.executable]
1130 if os.path.exists(pjoin(self.me_dir, 'bin', 'madevent')):1537 if os.path.exists(pjoin(self.me_dir, 'bin', 'madevent')):
@@ -1134,41 +1541,113 @@
1134 if not isinstance(self, cmd.CmdShell):1541 if not isinstance(self, cmd.CmdShell):
1135 command.append('--web')1542 command.append('--web')
1136 command.append('reweight')1543 command.append('reweight')
1137 if self.run_name:1544
1138 command.append(self.run_name)1545 ######### START SINGLE CORE MODE ############
1546 if self.options['nb_core']==1 or self.run_card['nevents'] < 101 or not check_multicore(self):
1547 if self.run_name:
1548 command.append(self.run_name)
1549 else:
1550 command += args
1551 if '-from_cards' not in command:
1552 command.append('-from_cards')
1553 p = misc.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, cwd=os.getcwd())
1554 while p.poll() is None:
1555 line = p.stdout.readline()
1556 if any(t in line for t in ['INFO:', 'WARNING:', 'CRITICAL:', 'ERROR:', 'root:','KEEP:']) and \
1557 not '***********' in line:
1558 print line[:-1].replace('INFO', 'REWEIGHT').replace('KEEP:','')
1559 elif __debug__ and line:
1560 logger.debug(line[:-1])
1561 if p.returncode !=0:
1562 logger.error("Reweighting failed")
1563 return
1564 self.results = self.load_results_db()
1565 # forbid this function to create an empty item in results.
1566 try:
1567 if self.results[self.run_name][-2]['cross']==0:
1568 self.results.delete_run(self.run_name,self.results[self.run_name][-2]['tag'])
1569 except:
1570 pass
1571 try:
1572 if self.results.current['cross'] == 0 and self.run_name:
1573 self.results.delete_run(self.run_name, self.run_tag)
1574 except:
1575 pass
1576 # re-define current run
1577 try:
1578 self.results.def_current(self.run_name, self.run_tag)
1579 except Exception:
1580 pass
1581 return
1582 ########## END SINGLE CORE HANDLING #############
1139 else:1583 else:
1140 command += args1584 ########## START MULTI-CORE HANDLING #############
1141 if '-from_cards' not in command:1585 if not isinstance(self.cluster, cluster.MultiCore):
1142 command.append('-from_cards')1586 mycluster = cluster.MultiCore(nb_core=self.options['nb_core'])
1143 p = misc.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, cwd=self.me_dir)1587 else:
1144 while p.poll() is None:1588 mycluster = self.cluster
1145 line = p.stdout.readline()1589
1146 if any(t in line for t in ['INFO:', 'WARNING:', 'CRITICAL:', 'ERROR:', 'root:','KEEP:']) and \1590 new_args=list(args)
1147 not '***********' in line:1591 self.check_decay_events(new_args)
1148 print line[:-1].replace('INFO', 'REWEIGHT').replace('KEEP:','')1592 try:
1149 elif __debug__ and line:1593 os.remove(pjoin(self.me_dir,'rw_me','rwgt.pkl'))
1150 logger.debug(line[:-1])1594 except Exception, error:
1151 if p.returncode !=0:1595 pass
1152 logger.error("Reweighting failed")1596 # prepare multi-core job:
1597 import madgraph.various.lhe_parser as lhe_parser
1598 # args now alway content the path to the valid files
1599 if 'nevt_job' in self.run_card and self.run_card['nevt_job'] !=-1:
1600 nevt_job = self.run_card['nevt_job']
1601 else:
1602 nevt_job = max(5000, self.run_card['nevents']/50)
1603 logger.info("split the event file in bunch of %s events" % nevt_job)
1604 nb_file = lhe_parser.EventFile(new_args[0]).split(nevt_job)
1605 starttime = time.time()
1606 update_status = lambda idle, run, finish: \
1607 self.update_status((idle, run, finish, 'reweight'), level=None,
1608 force=False, starttime=starttime)
1609
1610 all_lhe = []
1611 devnull= open(os.devnull)
1612 for i in range(nb_file):
1613 new_command = list(command)
1614 new_command.append('%s_%s.lhe' % (new_args[0],i))
1615 all_lhe.append('%s_%s.lhe' % (new_args[0],i))
1616 if '-from_cards' not in command:
1617 new_command.append('-from_cards')
1618 if i==0:
1619 if __debug__:
1620 stdout = None
1621 else:
1622 stdout = open(pjoin(self.me_dir,'Events', self.run_name, 'reweight.log'),'w')
1623 new_command.append('--multicore=create')
1624 else:
1625 stdout = devnull
1626 #stdout = open(pjoin(self.me_dir,'Events', self.run_name, 'reweight%s.log' % i),'w')
1627 new_command.append('--multicore=wait')
1628 mycluster.submit(prog=command[0], argument=new_command[1:], stdout=stdout, cwd=os.getcwd())
1629 mycluster.wait(self.me_dir,update_status)
1630 devnull.close()
1631
1632 lhe = lhe_parser.MultiEventFile(all_lhe, parse=False)
1633 nb_event, cross_sections = lhe.write(new_args[0], get_info=True)
1634 if any(os.path.exists('%s_%s_debug.log' % (f, self.run_tag)) for f in all_lhe):
1635 for f in all_lhe:
1636 if os.path.exists('%s_%s_debug.log' % (f, self.run_tag)):
1637 raise Exception, "Some of the run failed: Please read %s_%s_debug.log" % (f, self.run_tag)
1638
1639
1640 if 'event_norm' in self.run_card and self.run_card['event_norm'] == 'average':
1641 for key, value in cross_sections.items():
1642 cross_sections[key] = value / (nb_event+1)
1643 lhe.remove()
1644 for key in cross_sections:
1645 if key == 'orig' or key.isdigit():
1646 continue
1647 logger.info('%s : %s pb' % (key, cross_sections[key]))
1153 return1648 return
1154 self.results = self.load_results_db()1649 ########## END MULTI-CORE HANDLING #############
1155 # forbid this function to create an empty item in results.1650
1156 try:
1157 if self.results[self.run_name][-2]['cross']==0:
1158 self.results.delete_run(self.run_name,self.results[self.run_name][-2]['tag'])
1159 except:
1160 pass
1161 try:
1162 if self.results.current['cross'] == 0 and self.run_name:
1163 self.results.delete_run(self.run_name, self.run_tag)
1164 except:
1165 pass
1166 # re-define current run
1167 try:
1168 self.results.def_current(self.run_name, self.run_tag)
1169 except Exception:
1170 pass
1171 return
11721651
1173 self.to_store.append('event')1652 self.to_store.append('event')
1174 # forbid this function to create an empty item in results.1653 # forbid this function to create an empty item in results.
@@ -1189,6 +1668,8 @@
1189 path = pjoin(self.me_dir, 'Cards', 'reweight_card.dat')1668 path = pjoin(self.me_dir, 'Cards', 'reweight_card.dat')
1190 reweight_cmd.raw_input=False1669 reweight_cmd.raw_input=False
1191 reweight_cmd.me_dir = self.me_dir1670 reweight_cmd.me_dir = self.me_dir
1671 reweight_cmd.multicore = multicore #allow the directory creation or not
1672 print "We are in mode", multicore
1192 reweight_cmd.import_command_file(path)1673 reweight_cmd.import_command_file(path)
1193 reweight_cmd.do_quit('')1674 reweight_cmd.do_quit('')
1194 1675
@@ -2319,6 +2800,8 @@
23192800
2320 pdfsetname=set()2801 pdfsetname=set()
2321 for lhaid in lhaid_list:2802 for lhaid in lhaid_list:
2803 if isinstance(lhaid, str) and lhaid.isdigit():
2804 lhaid = int(lhaid)
2322 if isinstance(lhaid, (int,float)):2805 if isinstance(lhaid, (int,float)):
2323 try:2806 try:
2324 if lhaid in self.lhapdf_pdfsets:2807 if lhaid in self.lhapdf_pdfsets:
23252808
=== modified file 'madgraph/interface/madevent_interface.py'
--- madgraph/interface/madevent_interface.py 2016-08-17 19:36:40 +0000
+++ madgraph/interface/madevent_interface.py 2016-08-24 22:15:21 +0000
@@ -2012,11 +2012,17 @@
2012 if not bypass_run:2012 if not bypass_run:
2013 self.exec_cmd('refine %s' % nb_event, postcmd=False)2013 self.exec_cmd('refine %s' % nb_event, postcmd=False)
2014 2014
2015 self.exec_cmd('combine_events', postcmd=False)2015 self.exec_cmd('combine_events', postcmd=False,printcmd=False)
2016 self.print_results_in_shell(self.results.current)2016 self.print_results_in_shell(self.results.current)
20172017
2018 2018 if self.run_card['use_syst']:
2019 self.run_syscalc('parton')2019 scdir = self.options['syscalc_path']
2020 if not scdir or not os.path.exists(scdir):
2021 self.exec_cmd('systematics %s --from_card' % self.run_name, postcmd=False,printcmd=False)
2022 else:
2023 self.run_syscalc('parton')
2024
2025
2020 self.create_plot('parton') 2026 self.create_plot('parton')
2021 self.exec_cmd('store_events', postcmd=False) 2027 self.exec_cmd('store_events', postcmd=False)
2022 self.exec_cmd('reweight -from_cards', postcmd=False) 2028 self.exec_cmd('reweight -from_cards', postcmd=False)
@@ -3972,106 +3978,6 @@
3972 self.Gdirs = Gdirs3978 self.Gdirs = Gdirs
3973 return self.Gdirs3979 return self.Gdirs
3974 3980
3975 ############################################################################
3976 def set_run_name(self, name, tag=None, level='parton', reload_card=False,
3977 allow_new_tag=True):
3978 """define the run name, the run_tag, the banner and the results."""
3979
3980 # when are we force to change the tag new_run:previous run requiring changes
3981 upgrade_tag = {'parton': ['parton','pythia','pgs','delphes'],
3982 'pythia': ['pythia','pgs','delphes'],
3983 'pgs': ['pgs'],
3984 'delphes':['delphes'],
3985 'plot':[],
3986 'syscalc':[]}
3987
3988
3989
3990 if name == self.run_name:
3991 if reload_card:
3992 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
3993 self.run_card = banner_mod.RunCard(run_card)
3994
3995 #check if we need to change the tag
3996 if tag:
3997 self.run_card['run_tag'] = tag
3998 self.run_tag = tag
3999 self.results.add_run(self.run_name, self.run_card)
4000 else:
4001 for tag in upgrade_tag[level]:
4002 if getattr(self.results[self.run_name][-1], tag):
4003 tag = self.get_available_tag()
4004 self.run_card['run_tag'] = tag
4005 self.run_tag = tag
4006 self.results.add_run(self.run_name, self.run_card)
4007 break
4008 return # Nothing to do anymore
4009
4010 # save/clean previous run
4011 if self.run_name:
4012 self.store_result()
4013 # store new name
4014 self.run_name = name
4015
4016 new_tag = False
4017 # First call for this run -> set the banner
4018 self.banner = banner_mod.recover_banner(self.results, level, name)
4019 if 'mgruncard' in self.banner:
4020 self.run_card = self.banner.charge_card('run_card')
4021 else:
4022 # Read run_card
4023 run_card = pjoin(self.me_dir, 'Cards','run_card.dat')
4024 self.run_card = banner_mod.RunCard(run_card)
4025
4026 if tag:
4027 self.run_card['run_tag'] = tag
4028 new_tag = True
4029 elif not self.run_name in self.results and level =='parton':
4030 pass # No results yet, so current tag is fine
4031 elif not self.run_name in self.results:
4032 #This is only for case when you want to trick the interface
4033 logger.warning('Trying to run data on unknown run.')
4034 self.results.add_run(name, self.run_card)
4035 self.results.update('add run %s' % name, 'all', makehtml=False)
4036 else:
4037 for tag in upgrade_tag[level]:
4038
4039 if getattr(self.results[self.run_name][-1], tag):
4040 # LEVEL is already define in the last tag -> need to switch tag
4041 tag = self.get_available_tag()
4042 self.run_card['run_tag'] = tag
4043 new_tag = True
4044 break
4045 if not new_tag:
4046 # We can add the results to the current run
4047 tag = self.results[self.run_name][-1]['tag']
4048 self.run_card['run_tag'] = tag # ensure that run_tag is correct
4049
4050 if allow_new_tag and (name in self.results and not new_tag):
4051 self.results.def_current(self.run_name)
4052 else:
4053 self.results.add_run(self.run_name, self.run_card)
4054
4055 self.run_tag = self.run_card['run_tag']
4056
4057 # Return the tag of the previous run having the required data for this
4058 # tag/run to working wel.
4059 if level == 'parton':
4060 return
4061 elif level == 'pythia':
4062 return self.results[self.run_name][0]['tag']
4063 else:
4064 for i in range(-1,-len(self.results[self.run_name])-1,-1):
4065 tagRun = self.results[self.run_name][i]
4066 if tagRun.pythia:
4067 return tagRun['tag']
4068
4069
4070
4071
4072
4073
4074
40753981
4076 ############################################################################3982 ############################################################################
4077 def find_model_name(self):3983 def find_model_name(self):
@@ -4215,7 +4121,7 @@
4215 scdir = self.options['syscalc_path']4121 scdir = self.options['syscalc_path']
4216 if not scdir or not os.path.exists(scdir):4122 if not scdir or not os.path.exists(scdir):
4217 return4123 return
4218 logger.info('running syscalc on mode %s' % mode) 4124 logger.info('running SysCalc on mode %s' % mode)
4219 4125
42204126
4221 # Check that all pdfset are correctly installed4127 # Check that all pdfset are correctly installed
@@ -4265,7 +4171,9 @@
4265 if not (os.path.exists(event_path) or os.path.exists(event_path+".gz")):4171 if not (os.path.exists(event_path) or os.path.exists(event_path+".gz")):
4266 event_path = pjoin(event_dir, 'unweighted_events.lhe')4172 event_path = pjoin(event_dir, 'unweighted_events.lhe')
4267 output = pjoin(event_dir, 'syscalc.lhe')4173 output = pjoin(event_dir, 'syscalc.lhe')
4174 stdout = open(pjoin(event_dir, self.run_name, '%s_systematics.log' % (mode)),'w')
4268 elif mode == 'Pythia':4175 elif mode == 'Pythia':
4176 stdout = open(pjoin(event_dir, self.run_name, '%s_%s_syscalc.log' % (tag,mode)),'w')
4269 if 'mgpythiacard' in self.banner:4177 if 'mgpythiacard' in self.banner:
4270 pat = re.compile('''^\s*qcut\s*=\s*([\+\-\d.e]*)''', re.M+re.I)4178 pat = re.compile('''^\s*qcut\s*=\s*([\+\-\d.e]*)''', re.M+re.I)
4271 data = pat.search(self.banner['mgpythiacard'])4179 data = pat.search(self.banner['mgpythiacard'])
@@ -4294,7 +4202,7 @@
4294 try:4202 try:
4295 proc = misc.call([os.path.join(scdir, 'sys_calc'),4203 proc = misc.call([os.path.join(scdir, 'sys_calc'),
4296 event_path, card, output],4204 event_path, card, output],
4297 stdout = open(pjoin(event_dir, self.run_name, '%s_%s_syscalc.log' % (tag,mode)),'w'),4205 stdout = stdout,
4298 stderr = subprocess.STDOUT,4206 stderr = subprocess.STDOUT,
4299 cwd=event_dir)4207 cwd=event_dir)
4300 # Wait 5 s to make sure file is finished writing4208 # Wait 5 s to make sure file is finished writing
43014209
=== modified file 'madgraph/interface/madgraph_interface.py'
--- madgraph/interface/madgraph_interface.py 2016-08-22 20:43:28 +0000
+++ madgraph/interface/madgraph_interface.py 2016-08-24 22:15:21 +0000
@@ -192,9 +192,9 @@
192 info['date'])192 info['date'])
193193
194 if os.path.exists(pjoin(MG5DIR, '.bzr')):194 if os.path.exists(pjoin(MG5DIR, '.bzr')):
195 proc = subprocess.Popen(['bzr', 'nick'], stdout=subprocess.PIPE)195 proc = subprocess.Popen(['bzr', 'nick'], stdout=subprocess.PIPE,cwd=MG5DIR)
196 bzrname,_ = proc.communicate()196 bzrname,_ = proc.communicate()
197 proc = subprocess.Popen(['bzr', 'revno'], stdout=subprocess.PIPE)197 proc = subprocess.Popen(['bzr', 'revno'], stdout=subprocess.PIPE,cwd=MG5DIR)
198 bzrversion,_ = proc.communicate() 198 bzrversion,_ = proc.communicate()
199 bzrname, bzrversion = bzrname.strip(), bzrversion.strip() 199 bzrname, bzrversion = bzrname.strip(), bzrversion.strip()
200 len_name = len(bzrname)200 len_name = len(bzrname)
201201
=== modified file 'madgraph/interface/reweight_interface.py'
--- madgraph/interface/reweight_interface.py 2016-08-18 22:31:05 +0000
+++ madgraph/interface/reweight_interface.py 2016-08-24 22:15:21 +0000
@@ -82,11 +82,11 @@
82 self.model = None82 self.model = None
83 self.has_standalone_dir = False83 self.has_standalone_dir = False
84 self.mother= mother # calling interface84 self.mother= mother # calling interface
85 85 self.multicore=False
86 86
87 self.options = {'curr_dir': os.path.realpath(os.getcwd()),87 self.options = {'curr_dir': os.path.realpath(os.getcwd()),
88 'rwgt_name':None}88 'rwgt_name':None}
89 89
90 self.events_file = None90 self.events_file = None
91 self.processes = {}91 self.processes = {}
92 self.second_model = None92 self.second_model = None
@@ -201,7 +201,7 @@
201 logger.info("options: %s" % option)201 logger.info("options: %s" % option)
202202
203203
204 def get_LO_definition_from_NLO(self, proc):204 def get_LO_definition_from_NLO(self, proc, real_only=False):
205 """return the LO definitions of the process corresponding to the born/real"""205 """return the LO definitions of the process corresponding to the born/real"""
206 206
207 # split the line definition with the part before and after the NLO tag207 # split the line definition with the part before and after the NLO tag
@@ -212,7 +212,10 @@
212 #NO NLO tag => nothing to do actually return input212 #NO NLO tag => nothing to do actually return input
213 return proc213 return proc
214 elif not order.startswith(('virt','loonly','noborn')):214 elif not order.startswith(('virt','loonly','noborn')):
215 # OK this a standard NLO process215 # OK this a standard NLO process
216 if real_only:
217 commandline= ''
218
216 if '=' in order:219 if '=' in order:
217 # get the type NLO QCD/QED/...220 # get the type NLO QCD/QED/...
218 order = order.split('=',1)[1]221 order = order.split('=',1)[1]
@@ -358,6 +361,10 @@
358 self.rwgt_dir = args[1]361 self.rwgt_dir = args[1]
359 if not os.path.exists(self.rwgt_dir):362 if not os.path.exists(self.rwgt_dir):
360 os.mkdir(self.rwgt_dir)363 os.mkdir(self.rwgt_dir)
364 elif args[0] == 'multicore':
365 pass
366 # this line is meant to be parsed by common_run_interface and change the way this class is called.
367 #It has no direct impact on this class.
361 else:368 else:
362 logger.critical("unknown option! %s. Discard line." % args[0])369 logger.critical("unknown option! %s. Discard line." % args[0])
363 370
@@ -415,12 +422,25 @@
415422
416 model_line = self.banner.get('proc_card', 'full_model_line')423 model_line = self.banner.get('proc_card', 'full_model_line')
417424
418 if not self.has_standalone_dir:425 if not self.has_standalone_dir:
419 if self.rwgt_dir and os.path.exists(pjoin(self.rwgt_dir,'rw_me','rwgt.pkl')):426 if self.rwgt_dir and os.path.exists(pjoin(self.rwgt_dir,'rw_me','rwgt.pkl')):
420 self.load_from_pickle()427 self.load_from_pickle()
421 self.me_dir = self.rwgt_dir428 if not self.rwgt_dir:
429 self.me_dir = self.rwgt_dir
430 elif self.multicore == 'wait':
431 while not os.path.exists(pjoin(self.me_dir,'rw_me','rwgt.pkl')):
432 time.sleep(60)
433 print 'wait for pickle'
434 print "loading from pickle"
435 if not self.rwgt_dir:
436 self.rwgt_dir = self.me_dir
437 self.load_from_pickle(keep_name=True)
422 else:438 else:
423 self.create_standalone_directory() 439 self.create_standalone_directory()
440 if self.multicore == 'create':
441 if not self.rwgt_dir:
442 self.rwgt_dir = self.me_dir
443 self.save_to_pickle()
424 444
425 if self.rwgt_dir:445 if self.rwgt_dir:
426 path_me =self.rwgt_dir446 path_me =self.rwgt_dir
@@ -501,7 +521,6 @@
501 rewgtid = maxid521 rewgtid = maxid
502 if self.options['rwgt_name']:522 if self.options['rwgt_name']:
503 #ensure that the entry is not already define if so overwrites it523 #ensure that the entry is not already define if so overwrites it
504 misc.sprint(mg_rwgt_info)
505 for (i, nlotype, diff) in mg_rwgt_info[:]:524 for (i, nlotype, diff) in mg_rwgt_info[:]:
506 for flag in type_rwgt:525 for flag in type_rwgt:
507 if 'rwgt_%s' % i == '%s%s' %(self.options['rwgt_name'],flag) or \526 if 'rwgt_%s' % i == '%s%s' %(self.options['rwgt_name'],flag) or \
@@ -779,10 +798,11 @@
779 results.current.parton.append('lhe') 798 results.current.parton.append('lhe')
780 logger.info('Event %s is now created with new central weight' % output2.name)799 logger.info('Event %s is now created with new central weight' % output2.name)
781 800
782 for name in cross:801 if self.multicore != 'create':
783 if name == 'orig':802 for name in cross:
784 continue803 if name == 'orig':
785 logger.info('new cross-section is %s: %g pb (indicative error: %g pb)' %\804 continue
805 logger.info('new cross-section is %s: %g pb (indicative error: %g pb)' %\
786 ('(%s)' %name if name else '',cross[name], error[name]))806 ('(%s)' %name if name else '',cross[name], error[name]))
787 807
788 self.terminate_fortran_executables(new_card_only=True)808 self.terminate_fortran_executables(new_card_only=True)
@@ -1023,6 +1043,11 @@
1023 def calculate_matrix_element(self, event, hypp_id, space, scale2=0):1043 def calculate_matrix_element(self, event, hypp_id, space, scale2=0):
1024 """routine to return the matrix element"""1044 """routine to return the matrix element"""
1025 1045
1046 if self.has_nlo:
1047 nb_retry, sleep = 10, 60
1048 else:
1049 nb_retry, sleep = 5, 20
1050
1026 tag, order = event.get_tag_and_order()1051 tag, order = event.get_tag_and_order()
1027 if isinstance(hypp_id, str) and hypp_id.startswith('V'):1052 if isinstance(hypp_id, str) and hypp_id.startswith('V'):
1028 tag = (tag,'V')1053 tag = (tag,'V')
@@ -1068,7 +1093,7 @@
1068 dir_to_f2py_free_mod[(Pdir,0)] = (metag, nb_f2py_module)1093 dir_to_f2py_free_mod[(Pdir,0)] = (metag, nb_f2py_module)
1069 os.environ['MENUM'] = '2'1094 os.environ['MENUM'] = '2'
1070 if not self.rwgt_dir or not os.path.exists(pjoin(Pdir, 'matrix2py.so')):1095 if not self.rwgt_dir or not os.path.exists(pjoin(Pdir, 'matrix2py.so')):
1071 misc.compile(['matrix2py.so'], cwd=Pdir) 1096 misc.multiple_try(nb_retry,sleep)(misc.compile)(['matrix2py.so'], cwd=Pdir)
1072 self.rename_f2py_lib(Pdir, 2*metag)1097 self.rename_f2py_lib(Pdir, 2*metag)
1073 try:1098 try:
1074 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, 2*metag), globals(), locals(), [],-1)1099 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, 2*metag), globals(), locals(), [],-1)
@@ -1096,10 +1121,9 @@
1096 try:1121 try:
1097 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, newtag), globals(), locals(), [],-1)1122 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, newtag), globals(), locals(), [],-1)
1098 except Exception, error:1123 except Exception, error:
1099 os.remove(pjoin(Pdir, 'matrix%spy.so' % newtag))
1100 newtag = "L%s" % newtag1124 newtag = "L%s" % newtag
1101 os.environ['MENUM'] = newtag1125 os.environ['MENUM'] = newtag
1102 misc.compile(['matrix%spy.so' % newtag], cwd=Pdir)1126 misc.multiple_try(nb_retry,sleep)(misc.compile)(['matrix%spy.so' % newtag], cwd=Pdir)
1103 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, newtag), globals(), locals(), [],-1)1127 mymod = __import__('%s.SubProcesses.%s.matrix%spy' % (base, Pname, newtag), globals(), locals(), [],-1)
1104 1128
1105 S = mymod.SubProcesses1129 S = mymod.SubProcesses
@@ -1121,7 +1145,7 @@
1121 Pname = os.path.basename(Pdir)1145 Pname = os.path.basename(Pdir)
1122 os.environ['MENUM'] = '2'1146 os.environ['MENUM'] = '2'
1123 if not self.rwgt_dir or not os.path.exists(pjoin(Pdir, 'matrix2py.so')):1147 if not self.rwgt_dir or not os.path.exists(pjoin(Pdir, 'matrix2py.so')):
1124 misc.compile(['matrix2py.so'], cwd=pjoin(subdir, Pdir))1148 misc.multiple_try(nb_retry,sleep)(misc.compile)(['matrix2py.so'], cwd=pjoin(subdir, Pdir))
1125 if (Pdir, 1) not in dir_to_f2py_free_mod:1149 if (Pdir, 1) not in dir_to_f2py_free_mod:
1126 metag = 11150 metag = 1
1127 dir_to_f2py_free_mod[(Pdir,1)] = (metag, nb_f2py_module)1151 dir_to_f2py_free_mod[(Pdir,1)] = (metag, nb_f2py_module)
@@ -1134,10 +1158,9 @@
1134 try:1158 try:
1135 mymod = __import__("%s_second.SubProcesses.%s.matrix%spy" % (base, Pname, metag))1159 mymod = __import__("%s_second.SubProcesses.%s.matrix%spy" % (base, Pname, metag))
1136 except ImportError:1160 except ImportError:
1137 os.remove(pjoin(Pdir, 'matrix%spy.so' % metag ))
1138 metag = "L%s" % metag1161 metag = "L%s" % metag
1139 os.environ['MENUM'] = str(metag)1162 os.environ['MENUM'] = str(metag)
1140 misc.compile(['matrix%spy.so' % metag], cwd=pjoin(subdir, Pdir))1163 misc.multiple_try(nb_retry,sleep)(misc.compile)(['matrix%spy.so' % metag], cwd=pjoin(subdir, Pdir))
1141 mymod = __import__("%s_second.SubProcesses.%s.matrix%spy" % (base, Pname, metag))1164 mymod = __import__("%s_second.SubProcesses.%s.matrix%spy" % (base, Pname, metag))
1142 1165
1143 reload(mymod)1166 reload(mymod)
@@ -1211,21 +1234,24 @@
1211 split = line.split()1234 split = line.split()
1212 if len(split) == 4:1235 if len(split) == 4:
1213 cross, error = float(split[0]), float(split[1])1236 cross, error = float(split[0]), float(split[1])
1214 if 'orig' not in self.all_cross_section:1237
1215 logger.info('Original cross-section: %s +- %s pb' % (cross, error))1238 if not self.multicore == 'create':
1216 else: 1239 # No print of results for the multicore mode for the one printed on screen
1217 logger.info('Original cross-section: %s +- %s pb (cross-section from sum of weights: %s)' % (cross, error, self.all_cross_section['orig'][0]))1240 if 'orig' not in self.all_cross_section:
1218 logger.info('Computed cross-section:')1241 logger.info('Original cross-section: %s +- %s pb' % (cross, error))
1219 keys = self.all_cross_section.keys()1242 else:
1220 keys.sort()1243 logger.info('Original cross-section: %s +- %s pb (cross-section from sum of weights: %s)' % (cross, error, self.all_cross_section['orig'][0]))
1221 for key in keys:1244 logger.info('Computed cross-section:')
1222 if key == 'orig':1245 keys = self.all_cross_section.keys()
1223 continue1246 keys.sort()
1224 logger.info('%s : %s +- %s pb' % (key[0] if not key[1] else '%s%s' % key,1247 for key in keys:
1225 self.all_cross_section[key][0],self.all_cross_section[key][1] )) 1248 if key == 'orig':
1249 continue
1250 logger.info('%s : %s +- %s pb' % (key[0] if not key[1] else '%s%s' % key,
1251 self.all_cross_section[key][0],self.all_cross_section[key][1] ))
1226 self.terminate_fortran_executables()1252 self.terminate_fortran_executables()
1227 1253
1228 if self.rwgt_dir:1254 if self.rwgt_dir and self.multicore == False:
1229 self.save_to_pickle()1255 self.save_to_pickle()
1230 1256
1231 with misc.stdchannel_redirected(sys.stdout, os.devnull):1257 with misc.stdchannel_redirected(sys.stdout, os.devnull):
@@ -1245,7 +1271,7 @@
1245 @misc.mute_logger()1271 @misc.mute_logger()
1246 def create_standalone_directory(self, second=False):1272 def create_standalone_directory(self, second=False):
1247 """generate the various directory for the weight evaluation"""1273 """generate the various directory for the weight evaluation"""
1248 1274
1249 data={}1275 data={}
1250 if not second:1276 if not second:
1251 data['paths'] = ['rw_me', 'rw_mevirt']1277 data['paths'] = ['rw_me', 'rw_mevirt']
@@ -1350,12 +1376,18 @@
1350 logger.info('generating the square matrix element for reweighting (second model and/or processes)')1376 logger.info('generating the square matrix element for reweighting (second model and/or processes)')
1351 start = time.time()1377 start = time.time()
1352 commandline=''1378 commandline=''
1353 for proc in data['processes']:1379 for i,proc in enumerate(data['processes']):
1354 if '[' not in proc:1380 if '[' not in proc:
1355 commandline += "add process %s ;" % proc1381 commandline += "add process %s ;" % proc
1356 else:1382 else:
1357 has_nlo = True1383 has_nlo = True
1358 commandline += self.get_LO_definition_from_NLO(proc)1384 if self.banner.get('run_card','ickkw') == 3:
1385 if len(proc) == min([len(p.strip()) for p in data['processes']]):
1386 commandline += self.get_LO_definition_from_NLO(proc)
1387 else:
1388 commandline += self.get_LO_definition_from_NLO(proc, real_only=True)
1389 else:
1390 commandline += self.get_LO_definition_from_NLO(proc)
1359 1391
1360 commandline = commandline.replace('add process', 'generate',1)1392 commandline = commandline.replace('add process', 'generate',1)
1361 logger.info(commandline)1393 logger.info(commandline)
@@ -1434,6 +1466,18 @@
1434 pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat'), 1466 pjoin(path_me, data['paths'][0], 'Cards', 'MadLoopParams.dat'),
1435 commentdefault=False)1467 commentdefault=False)
1436 1468
1469 if self.multicore == 'create':
1470 print "compile OLP", data['paths'][0]
1471 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][0],'SubProcesses'),
1472 nb_core=self.mother.options['nb_core'])
1473
1474 if os.path.exists(pjoin(path_me, data['paths'][1], 'Cards', 'MadLoopParams.dat')):
1475 if self.multicore == 'create':
1476 print "compile OLP", data['paths'][1]
1477 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'),
1478 nb_core=self.mother.options['nb_core'])
1479
1480
1437 # 5. create the virtual for NLO reweighting ---------------------------1481 # 5. create the virtual for NLO reweighting ---------------------------
1438 if has_nlo and 'NLO' in self.rwgt_mode:1482 if has_nlo and 'NLO' in self.rwgt_mode:
1439 # Do not pass here for LO/NLO_tree1483 # Do not pass here for LO/NLO_tree
@@ -1527,6 +1571,11 @@
1527 self.banner.run_card['lpp2']],1571 self.banner.run_card['lpp2']],
1528 self.banner.run_card.get_lhapdf_id())1572 self.banner.run_card.get_lhapdf_id())
1529 self.combine_wgt = mymod.get_wgt1573 self.combine_wgt = mymod.get_wgt
1574
1575 if self.multicore == 'create':
1576 print "compile OLP", data['paths'][1]
1577 misc.compile(['OLP_static'], cwd=pjoin(path_me, data['paths'][1],'SubProcesses'),
1578 nb_core=self.mother.options['nb_core'])
1530 1579
1531 elif has_nlo and not second and self.rwgt_mode == ['NLO_tree']:1580 elif has_nlo and not second and self.rwgt_mode == ['NLO_tree']:
1532 # We do not have any virtual reweighting to do but we still have to1581 # We do not have any virtual reweighting to do but we still have to
@@ -1630,18 +1679,22 @@
1630 to_save['rwgt_dir'] = self.rwgt_dir1679 to_save['rwgt_dir'] = self.rwgt_dir
1631 to_save['has_nlo'] = self.has_nlo1680 to_save['has_nlo'] = self.has_nlo
1632 to_save['rwgt_mode'] = self.rwgt_mode1681 to_save['rwgt_mode'] = self.rwgt_mode
1682 to_save['rwgt_name'] = self.options['rwgt_name']
16331683
1634 name = pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl')1684 name = pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl')
1635 save_load_object.save_to_file(name, to_save)1685 save_load_object.save_to_file(name, to_save)
16361686
1637 def load_from_pickle(self):1687
1688 def load_from_pickle(self, keep_name=False):
1638 import madgraph.iolibs.save_load_object as save_load_object1689 import madgraph.iolibs.save_load_object as save_load_object
1639 1690
1640 obj = save_load_object.load_from_file( pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl'))1691 obj = save_load_object.load_from_file( pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl'))
1641 1692
1642 self.has_standalone_dir = True1693 self.has_standalone_dir = True
1643 self.options = {'curr_dir': os.path.realpath(os.getcwd()),1694 self.options = {'curr_dir': os.path.realpath(os.getcwd()),
1644 'rewgt_name': None}1695 'rwgt_name': None}
1696 if keep_name:
1697 self.options['rwgt_name'] = obj['rwgt_name']
1645 1698
1646 old_rwgt = obj['rwgt_dir']1699 old_rwgt = obj['rwgt_dir']
1647 1700
@@ -1665,10 +1718,14 @@
1665 if not self.rwgt_mode:1718 if not self.rwgt_mode:
1666 self.rwgt_mode = obj['rwgt_mode']1719 self.rwgt_mode = obj['rwgt_mode']
1667 logger.info("mode set to %s" % self.rwgt_mode)1720 logger.info("mode set to %s" % self.rwgt_mode)
1668 if self.has_nlo:1721 if self.has_nlo and 'NLO' in self.rwgt_mode:
1669 path = pjoin(obj['rwgt_dir'], 'rw_mevirt','Source')1722 path = pjoin(obj['rwgt_dir'], 'rw_mevirt','Source')
1670 sys.path.insert(0, path)1723 sys.path.insert(0, path)
1671 mymod = __import__('rwgt2py', globals(), locals())1724 try:
1725 mymod = __import__('rwgt2py', globals(), locals())
1726 except ImportError:
1727 misc.compile(['rwgt2py.so'], cwd=path)
1728 mymod = __import__('rwgt2py', globals(), locals())
1672 with misc.stdchannel_redirected(sys.stdout, os.devnull):1729 with misc.stdchannel_redirected(sys.stdout, os.devnull):
1673 mymod.initialise([self.banner.run_card['lpp1'], 1730 mymod.initialise([self.banner.run_card['lpp1'],
1674 self.banner.run_card['lpp2']],1731 self.banner.run_card['lpp2']],
16751732
=== modified file 'madgraph/iolibs/export_fks.py'
--- madgraph/iolibs/export_fks.py 2016-08-07 07:16:07 +0000
+++ madgraph/iolibs/export_fks.py 2016-08-24 22:15:21 +0000
@@ -268,7 +268,8 @@
268 pjoin('various','FO_analyse_card.py'),268 pjoin('various','FO_analyse_card.py'),
269 pjoin('various','histograms.py'), 269 pjoin('various','histograms.py'),
270 pjoin('various','banner.py'), 270 pjoin('various','banner.py'),
271 pjoin('various','cluster.py'), 271 pjoin('various','cluster.py'),
272 pjoin('various','systematics.py'),
272 pjoin('various','lhe_parser.py'),273 pjoin('various','lhe_parser.py'),
273 pjoin('madevent','sum_html.py'),274 pjoin('madevent','sum_html.py'),
274 pjoin('madevent','gen_crossxhtml.py'), 275 pjoin('madevent','gen_crossxhtml.py'),
275276
=== modified file 'madgraph/iolibs/export_v4.py'
--- madgraph/iolibs/export_v4.py 2016-08-15 14:06:30 +0000
+++ madgraph/iolibs/export_v4.py 2016-08-24 22:15:21 +0000
@@ -3227,6 +3227,8 @@
3227 self.dir_path+'/bin/internal/lhe_parser.py') 3227 self.dir_path+'/bin/internal/lhe_parser.py')
3228 cp(_file_path+'/various/banner.py', 3228 cp(_file_path+'/various/banner.py',
3229 self.dir_path+'/bin/internal/banner.py')3229 self.dir_path+'/bin/internal/banner.py')
3230 cp(_file_path+'/various/systematics.py', self.dir_path+'/bin/internal/systematics.py')
3231
3230 cp(_file_path+'/various/cluster.py', 3232 cp(_file_path+'/various/cluster.py',
3231 self.dir_path+'/bin/internal/cluster.py') 3233 self.dir_path+'/bin/internal/cluster.py')
3232 cp(_file_path+'/madevent/combine_runs.py', 3234 cp(_file_path+'/madevent/combine_runs.py',
32333235
=== modified file 'madgraph/madevent/gen_crossxhtml.py'
--- madgraph/madevent/gen_crossxhtml.py 2016-04-15 11:14:25 +0000
+++ madgraph/madevent/gen_crossxhtml.py 2016-08-24 22:15:21 +0000
@@ -812,7 +812,7 @@
812 self.parton.append('param_card')812 self.parton.append('param_card')
813 813
814 if 'syst' not in self.parton and \814 if 'syst' not in self.parton and \
815 exists(pjoin(path, "%s_parton_syscalc.log" %self['tag'])):815 exists(pjoin(path, "parton_systematics.log")):
816 self.parton.append('syst')816 self.parton.append('syst')
817817
818 for kind in ['top','HwU','pdf','ps']:818 for kind in ['top','HwU','pdf','ps']:
@@ -1150,8 +1150,8 @@
1150 local_dico['err'] = self['error']1150 local_dico['err'] = self['error']
1151 local_dico['nb_event'] = self['nb_event']1151 local_dico['nb_event'] = self['nb_event']
1152 if 'syst' in self.parton:1152 if 'syst' in self.parton:
1153 local_dico['syst'] = '<font face=symbol>&#177;</font> <a href="./Events/%(run_name)s/%(tag)s_parton_syscalc.log">systematics</a>' \1153 local_dico['syst'] = '<font face=symbol>&#177;</font> <a href="./Events/%(run_name)s/parton_systematics.log">systematics</a>' \
1154 % {'run_name':self['run_name'], 'tag': self['tag']}1154 % {'run_name':self['run_name']}
1155 elif self['cross_pythia']:1155 elif self['cross_pythia']:
1156 if self.parton:1156 if self.parton:
1157 local_dico['cross_span'] = nb_line -11157 local_dico['cross_span'] = nb_line -1
@@ -1173,7 +1173,7 @@
1173 local_dico['err'] = self['error']1173 local_dico['err'] = self['error']
1174 local_dico['nb_event'] = self['nb_event']1174 local_dico['nb_event'] = self['nb_event']
1175 if 'syst' in self.parton:1175 if 'syst' in self.parton:
1176 local_dico['syst'] = '<font face=symbol>&#177;</font> <a href="./Events/%(run_name)s/%(tag)s_parton_syscalc.log">systematics</a>' \1176 local_dico['syst'] = '<font face=symbol>&#177;</font> <a href="./Events/%(run_name)s/parton_systematics.log">systematics</a>' \
1177 % {'run_name':self['run_name'], 'tag': self['tag']}1177 % {'run_name':self['run_name'], 'tag': self['tag']}
1178 1178
1179 elif ttype == 'pythia' and self['cross_pythia']:1179 elif ttype == 'pythia' and self['cross_pythia']:
11801180
=== modified file 'madgraph/various/banner.py'
--- madgraph/various/banner.py 2016-08-17 19:36:40 +0000
+++ madgraph/various/banner.py 2016-08-24 22:15:21 +0000
@@ -193,34 +193,6 @@
193 return cross, math.sqrt(error)193 return cross, math.sqrt(error)
194 194
195195
196
197 def modify_init_cross(self, cross):
198 """modify the init information with the associate cross-section"""
199
200 assert isinstance(cross, dict)
201# assert "all" in cross
202 assert "init" in self
203
204 all_lines = self["init"].split('\n')
205 new_data = []
206 new_data.append(all_lines[0])
207 for i in range(1, len(all_lines)):
208 line = all_lines[i]
209 split = line.split()
210 if len(split) == 4:
211 xsec, xerr, xmax, pid = split
212 else:
213 new_data += all_lines[i:]
214 break
215 if int(pid) not in cross:
216 raise Exception
217 pid = int(pid)
218 ratio = cross[pid]/float(xsec)
219 line = " %+13.7e %+13.7e %+13.7e %i" % \
220 (float(cross[pid]), ratio* float(xerr), ratio*float(xmax), pid)
221 new_data.append(line)
222 self['init'] = '\n'.join(new_data)
223
224 def scale_init_cross(self, ratio):196 def scale_init_cross(self, ratio):
225 """modify the init information with the associate scale"""197 """modify the init information with the associate scale"""
226198
@@ -244,6 +216,15 @@
244 new_data.append(line)216 new_data.append(line)
245 self['init'] = '\n'.join(new_data)217 self['init'] = '\n'.join(new_data)
246 218
219 def get_pdg_beam(self):
220 """return the pdg of each beam"""
221
222 assert "init" in self
223
224 all_lines = self["init"].split('\n')
225 pdg1,pdg2,_ = all_lines[0].split(None, 2)
226 return int(pdg1), int(pdg2)
227
247 def load_basic(self, medir):228 def load_basic(self, medir):
248 """ Load the proc_card /param_card and run_card """229 """ Load the proc_card /param_card and run_card """
249 230
250231
=== modified file 'madgraph/various/cluster.py'
--- madgraph/various/cluster.py 2016-06-13 08:27:43 +0000
+++ madgraph/various/cluster.py 2016-08-24 22:15:21 +0000
@@ -618,6 +618,8 @@
618 if isinstance(exe,str):618 if isinstance(exe,str):
619 if os.path.exists(exe) and not exe.startswith('/'):619 if os.path.exists(exe) and not exe.startswith('/'):
620 exe = './' + exe620 exe = './' + exe
621 if isinstance(opt['stdout'],str):
622 opt['stdout'] = open(opt['stdout'],'w')
621 if opt['stderr'] == None:623 if opt['stderr'] == None:
622 opt['stderr'] = subprocess.STDOUT624 opt['stderr'] = subprocess.STDOUT
623 proc = misc.Popen([exe] + arg, **opt)625 proc = misc.Popen([exe] + arg, **opt)
@@ -673,7 +675,6 @@
673 675
674 tag = (prog, tuple(argument), cwd, nb_submit)676 tag = (prog, tuple(argument), cwd, nb_submit)
675 if isinstance(prog, str):677 if isinstance(prog, str):
676
677 678
678 opt = {'cwd': cwd, 679 opt = {'cwd': cwd,
679 'stdout':stdout,680 'stdout':stdout,
680681
=== modified file 'madgraph/various/lhe_parser.py'
--- madgraph/various/lhe_parser.py 2016-07-29 15:27:30 +0000
+++ madgraph/various/lhe_parser.py 2016-08-24 22:15:21 +0000
@@ -178,6 +178,8 @@
178 if '.gz' in path and isinstance(self, EventFileNoGzip) and\178 if '.gz' in path and isinstance(self, EventFileNoGzip) and\
179 mode == 'r' and os.path.exists(path[:-3]):179 mode == 'r' and os.path.exists(path[:-3]):
180 super(EventFile, self).__init__(path[:-3], mode, *args, **opt)180 super(EventFile, self).__init__(path[:-3], mode, *args, **opt)
181 else:
182 raise
181 183
182 self.banner = ''184 self.banner = ''
183 if mode == 'r':185 if mode == 'r':
@@ -506,7 +508,26 @@
506 else:508 else:
507 return out509 return out
508510
511 def split(self, nb_event=0):
512 """split the file in multiple file. Do not change the weight!"""
509 513
514 nb_file = -1
515 for i, event in enumerate(self):
516 if i % nb_event == 0:
517 if i:
518 #close previous file
519 current.write('</LesHouchesEvent>\n')
520 current.close()
521 # create the new file
522 nb_file +=1
523 current = open('%s_%s.lhe' % (self.name, nb_file),'w')
524 current.write(self.banner)
525 current.write(str(event))
526 if i!=0:
527 current.write('</LesHouchesEvent>\n')
528 current.close()
529 return nb_file +1
530
510 def update_Hwu(self, hwu, fct, name='lhe', keep_wgt=True):531 def update_Hwu(self, hwu, fct, name='lhe', keep_wgt=True):
511 532
512 first=True533 first=True
@@ -620,13 +641,14 @@
620 The number of events in each file need to be provide in advance 641 The number of events in each file need to be provide in advance
621 (if not provide the file is first read to find that number"""642 (if not provide the file is first read to find that number"""
622 643
623 def __new__(cls, start_list=[]):644 def __new__(cls, start_list=[],parse=True):
624 return object.__new__(MultiEventFile)645 return object.__new__(MultiEventFile)
625 646
626 def __init__(self, start_list=[]):647 def __init__(self, start_list=[], parse=True):
627 """if trunc_error is define here then this allow648 """if trunc_error is define here then this allow
628 to only read all the files twice and not three times."""649 to only read all the files twice and not three times."""
629 self.files = []650 self.files = []
651 self.parsefile = parse #if self.files is formatted or just the path
630 self.banner = ''652 self.banner = ''
631 self.initial_nb_events = []653 self.initial_nb_events = []
632 self.total_event_in_files = 0654 self.total_event_in_files = 0
@@ -636,8 +658,11 @@
636 self.across = []658 self.across = []
637 self.scales = []659 self.scales = []
638 if start_list:660 if start_list:
639 for p in start_list:661 if parse:
640 self.add(p)662 for p in start_list:
663 self.add(p)
664 else:
665 self.files = start_list
641 self._configure = False666 self._configure = False
642 667
643 def add(self, path, cross, error, across):668 def add(self, path, cross, error, across):
@@ -881,6 +906,66 @@
881906
882 return super(MultiEventFile, self).unweight(outputpath, get_wgt_multi, **opts)907 return super(MultiEventFile, self).unweight(outputpath, get_wgt_multi, **opts)
883908
909 def write(self, path, random=False, banner=None, get_info=False):
910 """ """
911
912 if isinstance(path, str):
913 out = EventFile(path, 'w')
914 if self.parsefile and not banner:
915 banner = self.files[0].banner
916 elif not banner:
917 firstlhe = EventFile(self.files[0])
918 banner = firstlhe.banner
919 else:
920 out = path
921 if banner:
922 out.write(banner)
923 nb_event = 0
924 info = collections.defaultdict(float)
925 if random and self.open:
926 for event in self:
927 nb_event +=1
928 out.write(event)
929 if get_info:
930 event.parse_reweight()
931 for key, value in event.reweight_data.items():
932 info[key] += value
933 info['central'] += event.wgt
934 elif not random:
935 for i,f in enumerate(self.files):
936 #check if we need to parse the file or not
937 if not self.parsefile:
938 if i==0:
939 try:
940 lhe = firstlhe
941 except:
942 lhe = EventFile(f)
943 else:
944 lhe = EventFile(f)
945 else:
946 lhe = f
947 for event in lhe:
948 nb_event +=1
949 if get_info:
950 event.parse_reweight()
951 for key, value in event.reweight_data.items():
952 info[key] += value
953 info['central'] += event.wgt
954 out.write(str(event))
955 lhe.close()
956 out.write("</LesHouchesEvents>\n")
957 return nb_event, info
958
959 def remove(self):
960 """ """
961 if self.parsefile:
962 for f in self.files:
963 os.remove(f.name)
964 else:
965 for f in self.files:
966 os.remove(f)
967
968
884 969
885class Event(list):970class Event(list):
886 """Class storing a single event information (list of particles + global information)"""971 """Class storing a single event information (list of particles + global information)"""
@@ -1025,7 +1110,7 @@
1025 self.reweight_order = []1110 self.reweight_order = []
1026 start, stop = self.tag.find('<rwgt>'), self.tag.find('</rwgt>')1111 start, stop = self.tag.find('<rwgt>'), self.tag.find('</rwgt>')
1027 if start != -1 != stop :1112 if start != -1 != stop :
1028 pattern = re.compile(r'''<\s*wgt id=(?:\'|\")(?P<id>[^\'\"]+)(?:\'|\")\s*>\s*(?P<val>[\ded+-.]*)\s*</wgt>''')1113 pattern = re.compile(r'''<\s*wgt id=(?:\'|\")(?P<id>[^\'\"]+)(?:\'|\")\s*>\s*(?P<val>[\ded+-.]*)\s*</wgt>''',re.I)
1029 data = pattern.findall(self.tag)1114 data = pattern.findall(self.tag)
1030 try:1115 try:
1031 self.reweight_data = dict([(pid, float(value)) for (pid, value) in data1116 self.reweight_data = dict([(pid, float(value)) for (pid, value) in data
@@ -1046,7 +1131,54 @@
1046 1131
1047 text = self.tag[start+8:stop]1132 text = self.tag[start+8:stop]
1048 self.nloweight = NLO_PARTIALWEIGHT(text, self)1133 self.nloweight = NLO_PARTIALWEIGHT(text, self)
1049 1134 return self.nloweight
1135
1136 def parse_lo_weight(self):
1137 """ """
1138 if hasattr(self, 'loweight'):
1139 return self.loweight
1140
1141 start, stop = self.tag.find('<mgrwt>'), self.tag.find('</mgrwt>')
1142
1143 if start != -1 != stop :
1144 text = self.tag[start+8:stop]
1145#<rscale> 3 0.29765919e+03</rscale>
1146#<asrwt>0</asrwt>
1147#<pdfrwt beam="1"> 1 21 0.15134321e+00 0.29765919e+03</pdfrwt>
1148#<pdfrwt beam="2"> 1 21 0.38683649e-01 0.29765919e+03</pdfrwt>
1149#<totfact> 0.17315115e+03</totfact>
1150 self.loweight={}
1151 for line in text.split('\n'):
1152 line = line.replace('<', ' <').replace("'",'"')
1153 if 'rscale' in line:
1154 _, nqcd, scale, _ = line.split()
1155 self.loweight['n_qcd'] = int(nqcd)
1156 self.loweight['ren_scale'] = float(scale)
1157 elif '<pdfrwt beam="1"' in line:
1158 args = line.split()
1159 self.loweight['n_pdfrw1'] = int(args[2])
1160 npdf = self.loweight['n_pdfrw1']
1161 self.loweight['pdf_pdg_code1'] = [int(i) for i in args[3:3+npdf]]
1162 self.loweight['pdf_x1'] = [float(i) for i in args[3+npdf:3+2*npdf]]
1163 self.loweight['pdf_q1'] = [float(i) for i in args[3+2*npdf:3+3*npdf]]
1164 elif '<pdfrwt beam="2"' in line:
1165 args = line.split()
1166 self.loweight['n_pdfrw2'] = int(args[2])
1167 npdf = self.loweight['n_pdfrw2']
1168 self.loweight['pdf_pdg_code2'] = [int(i) for i in args[3:3+npdf]]
1169 self.loweight['pdf_x2'] = [float(i) for i in args[3+npdf:3+2*npdf]]
1170 self.loweight['pdf_q2'] = [float(i) for i in args[3+2*npdf:3+3*npdf]]
1171 elif '<asrwt>' in line:
1172 args = line.replace('>','> ').split()
1173 nalps = int(args[1])
1174 self.loweight['asrwt'] = [float(a) for a in args[2:2+nalps]]
1175
1176 elif 'totfact' in line:
1177 args = line.split()
1178 self.loweight['tot_fact'] = float(args[1])
1179 else:
1180 return None
1181 return self.loweight
1050 1182
1051 def parse_matching_scale(self):1183 def parse_matching_scale(self):
1052 """Parse the line containing the starting scale for the shower"""1184 """Parse the line containing the starting scale for the shower"""
@@ -1608,10 +1740,40 @@
1608 for particle in self:1740 for particle in self:
1609 if particle.status != 1:1741 if particle.status != 1:
1610 continue 1742 continue
1611 scale += particle.mass**2 + particle.momentum.pt**21743 p = FourMomentum(particle)
1744 scale += math.sqrt(p.mass_sqr + p.pt**2)
1612 1745
1613 return prefactor * scale1746 return prefactor * scale
1614 1747
1748
1749 def get_et_scale(self, prefactor=1):
1750
1751 scale = 0
1752 for particle in self:
1753 if particle.status != 1:
1754 continue
1755 p = FourMomentum(particle)
1756 pt = p.pt
1757 if (pt>0):
1758 scale += p.E*pt/math.sqrt(pt**2+p.pz**2)
1759
1760 return prefactor * scale
1761
1762 def get_sqrts_scale(self, prefactor=1):
1763
1764 scale = 0
1765 init = []
1766 for particle in self:
1767 if particle.status == -1:
1768 init.append(FourMomentum(particle))
1769 if len(init) == 1:
1770 return init[0].mass
1771 elif len(init)==2:
1772 return math.sqrt((init[0]+init[1])**2)
1773
1774
1775
1776
1615 def get_momenta_str(self, get_order, allow_reversed=True):1777 def get_momenta_str(self, get_order, allow_reversed=True):
1616 """return the momenta str in the order asked for"""1778 """return the momenta str in the order asked for"""
1617 1779
@@ -1785,7 +1947,7 @@
1785 if power == 1:1947 if power == 1:
1786 return FourMomentum(self)1948 return FourMomentum(self)
1787 elif power == 2:1949 elif power == 2:
1788 return self.mass_sqr()1950 return self.mass_sqr
1789 1951
1790 def __repr__(self):1952 def __repr__(self):
1791 return 'FourMomentum(%s,%s,%s,%s)' % (self.E, self.px, self.py,self.pz)1953 return 'FourMomentum(%s,%s,%s,%s)' % (self.E, self.px, self.py,self.pz)
@@ -1850,6 +2012,20 @@
1850 if isinstance(input, str):2012 if isinstance(input, str):
1851 self.parse(input)2013 self.parse(input)
1852 2014
2015 def __str__(self):
2016
2017 out = """ pwgt: %(pwgt)s
2018 born, real : %(born)s %(real)s
2019 pdgs : %(pdgs)s
2020 bjks : %(bjks)s
2021 scales**2, gs: %(scales2)s %(gs)s
2022 born/real related : %(born_related)s %(real_related)s
2023 type / nfks : %(type)s %(nfks)s
2024 to merge : %(to_merge_pdg)s in %(merge_new_pdg)s
2025 ref_wgt : %(ref_wgt)s""" % self.__dict__
2026 return out
2027
2028
1853 def parse(self, text):2029 def parse(self, text):
1854 """parse the line and create the related object"""2030 """parse the line and create the related object"""
1855 #0.546601845792D+00 0.000000000000D+00 0.000000000000D+00 0.119210435309D+02 0.000000000000D+00 5 -1 2 -11 12 21 0 0.24546101D-01 0.15706890D-02 0.12586055D+04 0.12586055D+04 0.12586055D+04 1 2 2 2 5 2 2 0.539995789976D+042031 #0.546601845792D+00 0.000000000000D+00 0.000000000000D+00 0.119210435309D+02 0.000000000000D+00 5 -1 2 -11 12 21 0 0.24546101D-01 0.15706890D-02 0.12586055D+04 0.12586055D+04 0.12586055D+04 1 2 2 2 5 2 2 0.539995789976D+04
@@ -2086,6 +2262,42 @@
2086 @property2262 @property
2087 def aqcd(self):2263 def aqcd(self):
2088 return self.event.aqcd2264 return self.event.aqcd
2265
2266 def get_ht_scale(self, prefactor=1):
2267
2268 scale = 0
2269 for particle in self:
2270 p = particle
2271 scale += math.sqrt(max(0, p.mass_sqr + p.pt**2))
2272
2273 return prefactor * scale
2274
2275 def get_et_scale(self, prefactor=1):
2276
2277 scale = 0
2278 for particle in self:
2279 p = particle
2280 pt = p.pt
2281 if (pt>0):
2282 scale += p.E*pt/math.sqrt(pt**2+p.pz**2)
2283
2284 return prefactor * scale
2285
2286
2287 def get_sqrts_scale(self, event,prefactor=1):
2288
2289 scale = 0
2290 nb_init = 0
2291 for particle in event:
2292 if particle.status == -1:
2293 nb_init+=1
2294 if nb_init == 1:
2295 return self[0].mass
2296 elif nb_init==2:
2297 return math.sqrt((self[0]+self[1])**2)
2298
2299
2300
2089 2301
2090 def __init__(self, input, event):2302 def __init__(self, input, event):
2091 2303
20922304
=== modified file 'madgraph/various/misc.py'
--- madgraph/various/misc.py 2016-08-07 07:16:07 +0000
+++ madgraph/various/misc.py 2016-08-24 22:15:21 +0000
@@ -1334,6 +1334,7 @@
1334 if not __debug__:1334 if not __debug__:
1335 return1335 return
1336 1336
1337 use_print = False
1337 import inspect1338 import inspect
1338 if opt.has_key('cond') and not opt['cond']:1339 if opt.has_key('cond') and not opt['cond']:
1339 return1340 return
@@ -1346,6 +1347,8 @@
1346 level = opt['level']1347 level = opt['level']
1347 else:1348 else:
1348 level = logging.getLogger('madgraph').level1349 level = logging.getLogger('madgraph').level
1350 if level == 0:
1351 use_print = True
1349 #print "madgraph level",level1352 #print "madgraph level",level
1350 #if level == 20:1353 #if level == 20:
1351 # level = 10 #avoid info level1354 # level = 10 #avoid info level
@@ -1378,12 +1381,18 @@
1378 else:1381 else:
1379 intro = ''1382 intro = ''
1380 1383
13811384 if not use_print:
1382 log.log(level, ' '.join([intro]+[str(a) for a in args]) + \1385 log.log(level, ' '.join([intro]+[str(a) for a in args]) + \
1383 ' \033[1;30m[%s at line %s]\033[0m' % (os.path.basename(filename), lineno))1386 ' \033[1;30m[%s at line %s]\033[0m' % (os.path.basename(filename), lineno))
1387<<<<<<< TREE
13841388
1385 if wait:1389 if wait:
1386 raw_input('press_enter to continue')1390 raw_input('press_enter to continue')
1391=======
1392 else:
1393 print ' '.join([intro]+[str(a) for a in args]) + \
1394 ' \033[1;30m[%s at line %s]\033[0m' % (os.path.basename(filename), lineno)
1395>>>>>>> MERGE-SOURCE
1387 return 1396 return
13881397
1389################################################################################1398################################################################################
@@ -1606,6 +1615,7 @@
1606except:1615except:
1607 def apple_notify(subtitle, info_text, userInfo={}):1616 def apple_notify(subtitle, info_text, userInfo={}):
1608 return1617 return
1618<<<<<<< TREE
1609## End apple notify1619## End apple notify
16101620
16111621
@@ -1672,3 +1682,76 @@
1672 1682
1673 1683
16741684
1685=======
1686
1687
1688python_lhapdf=None
1689def import_python_lhapdf(lhapdfconfig):
1690 """load the python module of lhapdf return None if it can not be loaded"""
1691
1692 #save the result to have it faster and avoid the segfault at the second try if lhapdf is not compatible
1693 global python_lhapdf
1694 if python_lhapdf:
1695 if python_lhapdf == -1:
1696 return None
1697 else:
1698 return python_lhapdf
1699
1700 use_lhapdf=False
1701 try:
1702 lhapdf_libdir=subprocess.Popen([lhapdfconfig,'--libdir'],\
1703 stdout=subprocess.PIPE).stdout.read().strip()
1704 except:
1705 use_lhapdf=False
1706 return False
1707 else:
1708 try:
1709 candidates=[dirname for dirname in os.listdir(lhapdf_libdir) \
1710 if os.path.isdir(os.path.join(lhapdf_libdir,dirname))]
1711 except OSError:
1712 candidates=[]
1713 for candidate in candidates:
1714 if os.path.isfile(os.path.join(lhapdf_libdir,candidate,'site-packages','lhapdf.so')):
1715 sys.path.insert(0,os.path.join(lhapdf_libdir,candidate,'site-packages'))
1716 try:
1717 import lhapdf
1718 use_lhapdf=True
1719 break
1720 except ImportError:
1721 sys.path.pop(0)
1722 continue
1723 if not use_lhapdf:
1724 try:
1725 candidates=[dirname for dirname in os.listdir(lhapdf_libdir+'64') \
1726 if os.path.isdir(os.path.join(lhapdf_libdir+'64',dirname))]
1727 except OSError:
1728 candidates=[]
1729 for candidate in candidates:
1730 if os.path.isfile(os.path.join(lhapdf_libdir+'64',candidate,'site-packages','lhapdf.so')):
1731 sys.path.insert(0,os.path.join(lhapdf_libdir+'64',candidate,'site-packages'))
1732 try:
1733 import lhapdf
1734 use_lhapdf=True
1735 break
1736 except ImportError:
1737 sys.path.pop(0)
1738 continue
1739 if not use_lhapdf:
1740 try:
1741 import lhapdf
1742 use_lhapdf=True
1743 except ImportError:
1744 print 'fail'
1745 logger.warning("Failed to access python version of LHAPDF: "\
1746 "If the python interface to LHAPDF is available on your system, try "\
1747 "adding its location to the PYTHONPATH environment variable and the"\
1748 "LHAPDF library location to LD_LIBRARY_PATH (linux) or DYLD_LIBRARY_PATH (mac os x).")
1749
1750 if use_lhapdf:
1751 python_lhapdf = lhapdf
1752 python_lhapdf.setVerbosity(0)
1753 else:
1754 python_lhapdf = None
1755
1756 return python_lhapdf
1757>>>>>>> MERGE-SOURCE
16751758
=== added file 'madgraph/various/systematics.py'
--- madgraph/various/systematics.py 1970-01-01 00:00:00 +0000
+++ madgraph/various/systematics.py 2016-08-24 22:15:21 +0000
@@ -0,0 +1,724 @@
1################################################################################
2#
3# Copyright (c) 2016 The MadGraph5_aMC@NLO Development team and Contributors
4#
5# This file is a part of the MadGraph5_aMC@NLO project, an application which
6# automatically generates Feynman diagrams and matrix elements for arbitrary
7# high-energy processes in the Standard Model and beyond.
8#
9# It is subject to the MadGraph5_aMC@NLO license which should accompany this
10# distribution.
11#
12# For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch
13#
14################################################################################
15from __future__ import division
16if __name__ == "__main__":
17 import sys
18 import os
19 root = os.path.dirname(__file__)
20 if os.path.basename(root) == 'internal':
21 sys.path.append(os.path.dirname(root))
22 else:
23 sys.path.append(os.path.dirname(os.path.dirname(root)))
24
25import lhe_parser
26import banner
27import banner as banner_mod
28import itertools
29import misc
30import math
31import os
32import re
33import sys
34import time
35import StringIO
36
37pjoin = os.path.join
38
39class SystematicsError(Exception):
40 pass
41
42class Systematics(object):
43
44 def __init__(self, input_file, output_file,
45 start_event=0, stop_event=sys.maxint, write_banner=False,
46 mur=[0.5,1,2],
47 muf=[0.5,1,2],
48 alps=[1],
49 pdf='errorset', #[(id, subset)]
50 dyn=[-1,1,2,3,4],
51 together=[('mur', 'muf', 'dyn')],
52 lhapdf_config=misc.which('lhapdf-config'),
53 log=lambda x: sys.stdout.write(str(x)+'\n')
54 ):
55
56 # INPUT/OUTPUT FILE
57 if isinstance(input_file, str):
58 self.input = lhe_parser.EventFile(input_file)
59 else:
60 self.input = input_file
61 self.output_path = output_file
62 if output_file != None:
63 if isinstance(output_file, str):
64 if output_file == input_file:
65 directory,name = os.path.split(output_file)
66 new_name = pjoin(directory, '.tmp_'+name)
67 self.output = lhe_parser.EventFile(new_name, 'w')
68 else:
69 self.output = lhe_parser.EventFile(output_file, 'w')
70 else:
71 self.output = output_file
72 self.log = log
73
74 #get some information from the run_card.
75 self.banner = banner_mod.Banner(self.input.banner)
76 self.force_write_banner = bool(write_banner)
77 self.orig_dyn = self.banner.get('run_card', 'dynamical_scale_choice')
78 self.orig_pdf = self.banner.run_card.get_lhapdf_id()
79
80 #check for beam
81 beam1, beam2 = self.banner.get_pdg_beam()
82 if abs(beam1) != 2212 and abs(beam2) != 2212:
83 raise SystematicsError, 'can only reweight proton beam'
84 elif abs(beam1) != 2212:
85 self.b1 = 0
86 self.b2 = beam2//2212
87 elif abs(beam2) != 2212:
88 self.b1 = beam1//2212
89 self.b2 = 0
90 else:
91 self.b1 = beam1//2212
92 self.b2 = beam2//2212
93
94 if isinstance(self.banner.run_card, banner_mod.RunCardLO):
95 self.is_lo = True
96 if not self.banner.run_card['use_syst']:
97 raise SystematicsError, 'The events was not generated with use_syst=True. Can not evaluate systematics error on this event.'
98 else:
99 self.is_lo = False
100 if not self.banner.run_card['store_rwgt_info']:
101 raise SystematicsError, 'The events was not generated with store_rwgt_info=True. Can not evaluate systematics error on this event.'
102
103 # MUR/MUF/ALPS PARSING
104 if isinstance(mur, str):
105 mur = mur.split(',')
106 self.mur=[float(i) for i in mur]
107 if isinstance(muf, str):
108 muf = muf.split(',')
109 self.muf=[float(i) for i in muf]
110
111 if isinstance(alps, str):
112 alps = alps.split(',')
113 self.alps=[float(i) for i in alps]
114
115 # DYNAMICAL SCALE PARSING + together
116 if isinstance(dyn, str):
117 dyn = dyn.split(',')
118 self.dyn=[int(i) for i in dyn]
119
120 if isinstance(together, str):
121 self.together = together.split(',')
122 else:
123 self.together = together
124
125 # START/STOP EVENT
126 self.start_event=int(start_event)
127 self.stop_event=int(stop_event)
128 if start_event != 0:
129 self.log( "#starting from event #%s" % start_event)
130 if stop_event != sys.maxint:
131 self.log( "#stopping at event #%s" % stop_event)
132
133 # LHAPDF set
134 if isinstance(lhapdf_config, list):
135 lhapdf_config = lhapdf_config[0]
136 lhapdf = misc.import_python_lhapdf(lhapdf_config)
137 if not lhapdf:
138 return
139 lhapdf.setVerbosity(0)
140 self.pdfsets = {}
141 if isinstance(pdf, str):
142 pdf = pdf.split(',')
143
144 if isinstance(pdf,list) and isinstance(pdf[0],(str,int)):
145 self.pdf = []
146 for data in pdf:
147 if data == 'errorset':
148 data = '%s' % self.orig_pdf
149 if data == 'central':
150 data = '%s@0' % self.orig_pdf
151 if '@' in data:
152 #one particular dataset
153 name, arg = data.rsplit('@',1)
154 if int(arg) == 0:
155 if name.isdigit():
156 self.pdf.append(lhapdf.mkPDF(int(name)))
157 else:
158 self.pdf.append(lhapdf.mkPDF(name))
159 elif name.isdigit():
160 try:
161 self.pdf.append(lhapdf.mkPDF(int(name)+int(arg)))
162 except:
163 raise Exception, 'invididual error set need to called with name not with lhapdfID'
164 else:
165 self.pdf.append(lhapdf.mkPDF(name, int(arg)))
166 else:
167 if data.isdigit():
168 pdfset = lhapdf.mkPDF(int(data)).set()
169 else:
170 pdfset = lhapdf.mkPDF(data).set()
171 self.pdfsets[pdfset.lhapdfID] = pdfset
172 self.pdf += pdfset.mkPDFs()
173 else:
174 self.pdf = pdf
175
176 for p in self.pdf:
177 if p.lhapdfID == self.orig_pdf:
178 self.orig_pdf = p
179 break
180 else:
181 self.orig_pdf = lhapdf.mkPDF(self.orig_pdf)
182 self.log( "# events generated with PDF: %s (%s)" %(self.orig_pdf.set().name,self.orig_pdf.lhapdfID ))
183 # create all the function that need to be called
184 self.get_all_fct() # define self.fcts and self.args
185
186 def run(self, stdout=sys.stdout):
187 """ """
188 start_time = time.time()
189 if self.start_event == 0 or self.force_write_banner:
190 lowest_id = self.write_banner(self.output)
191 else:
192 lowest_id = self.get_id()
193
194 ids = [lowest_id+i for i in range(len(self.args)-1)]
195 all_cross = [0 for i in range(len(self.args))]
196
197 for nb_event,event in enumerate(self.input):
198 if nb_event < self.start_event:
199 continue
200 elif nb_event >= self.stop_event:
201 if self.force_write_banner:
202 self.output.write('</LesHouchesEvents>\n')
203 break
204 if self.is_lo:
205 if (nb_event-self.start_event)>=0 and (nb_event-self.start_event) % 2500 ==0:
206 self.log( '# currently at event %s [ellapsed time: %.2g s]' % (nb_event, time.time()-start_time))
207 else:
208 if (nb_event-self.start_event)>=0 and (nb_event-self.start_event) % 1000 ==0:
209 self.log( '# currently at event %i [ellapsed time: %.2g s]' % (nb_event, time.time()-start_time))
210
211 self.new_event() #re-init the caching of alphas/pdf
212 if self.is_lo:
213 wgts = [self.get_lo_wgt(event, *arg) for arg in self.args]
214 else:
215 wgts = [self.get_nlo_wgt(event, *arg) for arg in self.args]
216
217 if wgts[0] == 0:
218 print wgts
219 print event
220 raise Exception
221
222 wgt = [event.wgt*wgts[i]/wgts[0] for i in range(1,len(wgts))]
223 all_cross = [(all_cross[j] + event.wgt*wgts[j]/wgts[0]) for j in range(len(wgts))]
224
225 rwgt_data = event.parse_reweight()
226 rwgt_data.update(zip(ids, wgt))
227 event.reweight_order += ids
228 # order the
229 self.output.write(str(event))
230 else:
231 self.output.write('</LesHouchesEvents>\n')
232 self.output.close()
233 self.print_cross_sections(all_cross, min(nb_event,self.stop_event)-self.start_event+1, stdout)
234
235 if self.output.name != self.output_path:
236 import shutil
237 shutil.move(self.output.name, self.output_path)
238
239 return all_cross
240
241 def print_cross_sections(self, all_cross, nb_event, stdout):
242 """print the cross-section."""
243
244 norm = self.banner.get('run_card', 'event_norm', default='sum')
245 #print "normalisation is ", norm
246 #print "nb_event is ", nb_event
247
248 max_scale, min_scale = 0,sys.maxint
249 max_alps, min_alps = 0, sys.maxint
250 max_dyn, min_dyn = 0,sys.maxint
251 pdfs = {}
252 dyns = {} # dyn : {'max': , 'min':}
253
254 if norm == 'sum':
255 norm = 1
256 elif norm == 'average':
257 norm = 1./nb_event
258 elif norm == 'unity':
259 norm = 1
260
261 all_cross = [c*norm for c in all_cross]
262 stdout.write("# mur\t\tmuf\t\talpsfact\tdynamical_scale\tpdf\t\tcross-section\n")
263 for i,arg in enumerate(self.args):
264
265 to_print = list(arg)
266 to_print[4] = to_print[4].lhapdfID
267 to_print.append(all_cross[i])
268 to_report = []
269 stdout.write('%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\n' % tuple(to_print))
270
271 mur, muf, alps, dyn, pdf = arg[:5]
272 if pdf == self.orig_pdf and (dyn==self.orig_dyn or dyn==-1)\
273 and (mur!=1 or muf!=1 or alps!=1):
274 max_scale = max(max_scale,all_cross[i])
275 min_scale = min(min_scale,all_cross[i])
276 if pdf == self.orig_pdf and mur==1 and muf==1 and \
277 (dyn==self.orig_dyn or dyn==-1) and alps!=1:
278 max_alps = max(max_alps,all_cross[i])
279 min_alps = min(min_alps,all_cross[i])
280
281 if pdf == self.orig_pdf and mur==1 and muf==1 and alps==1:
282 max_dyn = max(max_dyn,all_cross[i])
283 min_dyn = min(min_dyn,all_cross[i])
284
285 if pdf == self.orig_pdf and (alps!=1 or mur!=1 or muf!=1) and \
286 (dyn!=self.orig_dyn or dyn!=-1):
287 if dyn not in dyns:
288 dyns[dyn] = {'max':0, 'min':sys.maxint,'central':0}
289 curr = dyns[dyn]
290 curr['max'] = max(curr['max'],all_cross[i])
291 curr['min'] = min(curr['min'],all_cross[i])
292 if pdf == self.orig_pdf and (alps==1 and mur==1 and muf==1) and \
293 (dyn!=self.orig_dyn or dyn!=-1):
294 if dyn not in dyns:
295 dyns[dyn] = {'max':0, 'min':sys.maxint,'central':all_cross[i]}
296 else:
297 dyns[dyn]['central'] = all_cross[i]
298
299 if alps==1 and mur==1 and muf==1 and (dyn==self.orig_dyn or dyn==-1):
300 pdfset = pdf.set()
301 if pdfset.lhapdfID in self.pdfsets:
302 if pdfset.lhapdfID not in pdfs :
303 pdfs[pdfset.lhapdfID] = [0] * pdfset.size
304 pdfs[pdfset.lhapdfID][pdf.memberID] = all_cross[i]
305 else:
306 to_report.append('# PDF %s : %s\n' % (pdf.lhapdfID, all_cross[i]))
307
308 stdout.write('\n')
309
310 resume = StringIO.StringIO()
311
312 resume.write( '#***************************************************************************\n')
313 resume.write( "#\n")
314 resume.write( '# original cross-section: %s\n' % all_cross[0])
315 if max_scale:
316 resume.write( '# scale variation: +%2.3g%% -%2.3g%%\n' % ((max_scale-all_cross[0])/all_cross[0]*100,(all_cross[0]-min_scale)/all_cross[0]*100))
317 if max_alps:
318 resume.write( '# emission scale variation: +%2.3g%% -%2.3g%%\n' % ((max_alps-all_cross[0])/all_cross[0]*100,(max_alps-min_scale)/all_cross[0]*100))
319 if max_dyn and (max_dyn!= all_cross[0] or min_dyn != all_cross[0]):
320 resume.write( '# central scheme variation: +%2.3g%% -%2.3g%%\n' % ((max_dyn-all_cross[0])/all_cross[0]*100,(all_cross[0]-min_dyn)/all_cross[0]*100))
321 if self.orig_pdf.lhapdfID in pdfs:
322 lhapdfid = self.orig_pdf.lhapdfID
323 values = pdfs[lhapdfid]
324 pdfset = self.pdfsets[lhapdfid]
325 pdferr = pdfset.uncertainty(values)
326 resume.write( '# PDF variation: +%2.3g%% -%2.3g%%\n' % (pdferr.errplus*100/all_cross[0], pdferr.errminus*100/all_cross[0]))
327 # report error/central not directly linked to the central
328 resume.write( "#\n")
329 for lhapdfid,values in pdfs.items():
330 if lhapdfid == self.orig_pdf.lhapdfID:
331 continue
332 pdfset = self.pdfsets[lhapdfid]
333 pdferr = pdfset.uncertainty(values)
334 resume.write( '#PDF %s: %g +%2.3g%% -%2.3g%%\n' % (pdfset.name, pdferr.central,pdferr.errplus*100/all_cross[0], pdferr.errminus*100/all_cross[0]))
335
336 dyn_name = {1: '\sum ET', 2:'\sum\sqrt{m^2+pt^2}', 3:'0.5 \sum\sqrt{m^2+pt^2}',4:'\sqrt{\hat s}' }
337 for key, curr in dyns.items():
338 if key ==-1:
339 continue
340 central, maxvalue, minvalue = curr['central'], curr['max'], curr['min']
341 if central == 0:
342 continue
343 if maxvalue == 0:
344 resume.write("# dynamical scheme # %s : %g # %s\n" %(key, central, dyn_name[key]))
345 else:
346 resume.write("# dynamical scheme # %s : %g +%2.3g%% -%2.3g%% # %s\n" %(key, central, (maxvalue-central)/central*100,(central-minvalue)/central*100, dyn_name[key]))
347
348 resume.write('\n'.join(to_report))
349
350 resume.write( '#***************************************************************************\n')
351
352 stdout.write(resume.getvalue())
353 self.log(resume.getvalue())
354
355
356 def write_banner(self, fsock):
357 """create the new banner with the information of the weight"""
358
359 cid = self.get_id()
360 lowest_id = cid
361
362 in_scale = False
363 in_pdf = False
364 in_alps = False
365
366 text = ''
367
368 for arg in self.args[1:]:
369 mur, muf, alps, dyn, pdf = arg[:5]
370 if pdf == self.orig_pdf and alps ==1 and (mur!=1 or muf!=1 or dyn!=-1):
371 if not in_scale:
372 text += "<weightgroup name=\"Central scale variation\" combine=\"envelope\">\n"
373 in_scale=True
374 elif in_scale:
375 if (pdf == self.orig_pdf and alps ==1):
376 pass
377 else:
378 text += "</weightgroup> # scale\n"
379 in_scale = False
380
381 if pdf == self.orig_pdf and mur == muf == 1 and dyn==-1 and alps!=1:
382 if not in_alps:
383 text += "<weightgroup name=\"Emission scale variation\" combine=\"envelope\">\n"
384 in_alps=True
385 elif in_alps:
386 text += "</weightgroup> # ALPS\n"
387 in_alps=False
388
389 if pdf != self.orig_pdf and mur == muf == 1 and dyn==-1 and alps ==1:
390 if pdf.lhapdfID in self.pdfsets:
391 if in_pdf:
392 text += "</weightgroup> # PDFSET -> PDFSET\n"
393 pdfset = self.pdfsets[pdf.lhapdfID]
394 text +="<weightgroup name=\"%s\" combine=\"%s\"> # %s: %s\n" %\
395 (pdfset.name, pdfset.errorType,pdfset.lhapdfID, pdfset.description)
396 in_pdf=pdf.lhapdfID
397 elif pdf.memberID == 1 and (pdf.lhapdfID - pdf.memberID) in self.pdfsets:
398 if in_pdf:
399 text += "</weightgroup> # PDFSET -> PDFSET\n"
400 pdfset = self.pdfsets[pdf.lhapdfID - 1]
401 text +="<weightgroup name=\"%s\" combine=\"%s\"> # %s: %s\n" %\
402 (pdfset.name, pdfset.errorType,pdfset.lhapdfID, pdfset.description)
403 in_pdf=pdfset.lhapdfID
404 elif in_pdf and pdf.lhapdfID - pdf.memberID != in_pdf:
405 text += "</weightgroup> # PDFSET -> PDF\n"
406 in_pdf = False
407 elif in_pdf:
408 text += "</weightgroup> PDF \n"
409 in_pdf=False
410
411
412
413 tag, info = '',''
414 if mur!=1.:
415 tag += 'MUR="%s" ' % mur
416 info += 'MUR=%s ' % mur
417 else:
418 tag += 'MUR="%s" ' % mur
419 if muf!=1.:
420 tag += 'MUF="%s" ' % muf
421 info += 'MUF=%s ' % muf
422 else:
423 tag += 'MUF="%s" ' % muf
424
425 if alps!=1.:
426 tag += 'ALPSFACT="%s" ' % alps
427 info += 'alpsfact=%s ' % alps
428 if dyn!=-1.:
429 tag += 'DYN_SCALE="%s" ' % dyn
430 info += 'dyn_scale_choice=%s ' % {1:'sum pt', 2:'HT',3:'HT/2',4:'sqrts'}[dyn]
431
432 if pdf != self.orig_pdf:
433 tag += 'LHAPDF="%s" ' % pdf.lhapdfID
434 info += 'LHAPDF=%s MemberID=%s' % (pdf.lhapdfID-pdf.memberID, pdf.memberID)
435 else:
436 tag += 'LHAPDF="%s" ' % pdf.lhapdfID
437
438 text +='<weight id="%s" %s> %s </weight>\n' % (cid, tag, info)
439 cid+=1
440
441 if in_scale or in_alps or in_pdf:
442 text += "</weightgroup>\n"
443
444 if 'initrwgt' in self.banner:
445 self.banner['initrwgt'] += text
446 else:
447 self.banner['initrwgt'] = text
448
449
450 self.banner.write(self.output, close_tag=False)
451
452 return lowest_id
453
454
455 def get_id(self):
456
457 if 'initrwgt' in self.banner:
458 pattern = re.compile('<weight id=(?:\'|\")([_\w]+)(?:\'|\")', re.S+re.I+re.M)
459 return max([int(wid) for wid in pattern.findall(self.banner['initrwgt'])])+1
460 else:
461 return 1
462
463
464
465
466 def get_all_fct(self):
467
468 all_args = []
469 default = [1.,1.,1.,-1,self.orig_pdf]
470 #all_args.append(default)
471 pos = {'mur':0, 'muf':1, 'alps':2, 'dyn':3, 'pdf':4}
472 done = set()
473 for one_block in self.together:
474 for name in one_block:
475 done.add(name)
476 for together in itertools.product(*[getattr(self,name) for name in one_block]):
477 new_args = list(default)
478 for name,value in zip(one_block, together):
479 new_args[pos[name]] = value
480 all_args.append(new_args)
481 for name in pos:
482 if name in done:
483 continue
484 for value in getattr(self, name):
485 new_args = list(default)
486 new_args[pos[name]] = value
487 all_args.append(new_args)
488
489 self.args = [default]+ [arg for arg in all_args if arg!= default]
490
491 self.log( "#Will Compute %s weights per event." % (len(self.args)-1))
492 return
493
494 def new_event(self):
495 self.alphas = {}
496 self.pdfQ2 = {}
497
498
499 def get_pdfQ(self, pdf, pdg, x, scale):
500
501 if pdg in [-21,-22]:
502 pdg = abs(pdg)
503 elif pdg == 0:
504 return 1
505
506 f = pdf.xfxQ(pdg, x, scale)/x
507# if f == 0 and pdf.memberID ==0:
508# pdfset = pdf.set()
509# allnumber= [p.xfxQ(pdg, x, scale) for p in pdfset.mkPDFs()]
510# f = pdfset.uncertainty(allnumber).central /x
511 return f
512
513 def get_pdfQ2(self, pdf, pdg, x, scale):
514
515 if pdg in [-21,-22]:
516 pdg = abs(pdg)
517 elif pdg == 0:
518 return 1
519
520 if (pdf, pdg,x,scale) in self.pdfQ2:
521 return self.pdfQ2[(pdf, pdg,x,scale)]
522 f = pdf.xfxQ2(pdg, x, scale)/x
523 self.pdfQ2[(pdf, pdg,x,scale)] = f
524 return f
525
526 #one method to handle the nnpd2.3 problem -> now just move to central
527 if f == 0 and pdf.memberID ==0:
528 # to avoid problem with nnpdf2.3 in lhapdf6.1.6
529 #print 'central pdf returns 0', pdg, x, scale
530 #print self.pdfsets
531 pdfset = pdf.set()
532 allnumber= [0] + [self.get_pdfQ2(p, pdg, x, scale) for p in pdfset.mkPDFs()[1:]]
533 f = pdfset.uncertainty(allnumber).central
534 self.pdfQ2[(pdf, pdg,x,scale)] = f
535 return f
536
537 def get_lo_wgt(self,event, Dmur, Dmuf, Dalps, dyn, pdf):
538 """
539 pdf is a lhapdf object!"""
540
541 loinfo = event.parse_lo_weight()
542
543 if dyn == -1:
544 mur = loinfo['ren_scale']
545 muf1 = loinfo['pdf_q1'][-1]
546 muf2 = loinfo['pdf_q2'][-1]
547 else:
548 if dyn == 1:
549 mur = event.get_et_scale(1.)
550 elif dyn == 2:
551 mur = event.get_ht_scale(1.)
552 elif dyn == 3:
553 mur = event.get_ht_scale(0.5)
554 elif dyn == 4:
555 mur = event.get_sqrts_scale(1.)
556 muf1 = mur
557 muf2 = mur
558 loinfo['pdf_q1'][-1] = mur
559 loinfo['pdf_q2'][-1] = mur
560
561
562 # MUR part
563 wgt = pdf.alphasQ(Dmur*mur)**loinfo['n_qcd']
564 # MUF/PDF part
565 wgt *= self.get_pdfQ(pdf, self.b1*loinfo['pdf_pdg_code1'][-1], loinfo['pdf_x1'][-1], Dmuf*muf1)
566 wgt *= self.get_pdfQ(pdf, self.b2*loinfo['pdf_pdg_code2'][-1], loinfo['pdf_x2'][-1], Dmuf*muf2)
567
568 for scale in loinfo['asrwt']:
569 wgt *= pdf.alphasQ(Dalps*scale)
570
571 # ALS part
572 for i in range(loinfo['n_pdfrw1']-1):
573 scale = min(Dalps*loinfo['pdf_q1'][i], Dmuf*muf1)
574 wgt *= self.get_pdfQ(pdf, self.b1*loinfo['pdf_pdg_code1'][i], loinfo['pdf_x1'][i], scale)
575 wgt /= self.get_pdfQ(pdf, self.b1*loinfo['pdf_pdg_code1'][i], loinfo['pdf_x1'][i+1], scale)
576
577 for i in range(loinfo['n_pdfrw2']-1):
578 scale = min(Dalps*loinfo['pdf_q2'][i], Dmuf*muf2)
579 wgt *= self.get_pdfQ(pdf, self.b2*loinfo['pdf_pdg_code2'][i], loinfo['pdf_x2'][i], scale)
580 wgt /= self.get_pdfQ(pdf, self.b2*loinfo['pdf_pdg_code2'][i], loinfo['pdf_x2'][i+1], scale)
581
582 return wgt
583
584 def get_nlo_wgt(self,event, Dmur, Dmuf, Dalps, dyn, pdf):
585 """return the new weight for NLO event --with weight information-- """
586
587 wgt = 0
588 nloinfo = event.parse_nlo_weight()
589 for cevent in nloinfo.cevents:
590 if dyn == 1:
591 mur2 = cevent.get_et_scale(1.)**2
592 elif dyn == 2:
593 mur2 = cevent.get_ht_scale(1.)**2
594 elif dyn == 3:
595 mur2 = cevent.get_ht_scale(0.5)**2
596 elif dyn == 4:
597 mur2 = cevent.get_sqrts_scale(event,1)**2
598 else:
599 mur2 = 0
600 muf2 = mur2
601
602 for onewgt in cevent.wgts:
603 if dyn == -1:
604 mur2 = onewgt.scales2[1]
605 muf2 = onewgt.scales2[2]
606 Q2 = onewgt.scales2[0] # Ellis-Sexton scale
607
608 wgtpdf = self.get_pdfQ2(pdf, self.b1*onewgt.pdgs[0], onewgt.bjks[0],
609 Dmuf**2 * muf2)
610 wgtpdf *= self.get_pdfQ2(pdf, self.b2*onewgt.pdgs[1], onewgt.bjks[1],
611 Dmuf**2 * muf2)
612
613 tmp = onewgt.pwgt[0]
614 tmp += onewgt.pwgt[1] * math.log(Dmur**2 * mur2/ Q2)
615 tmp += onewgt.pwgt[2] * math.log(Dmuf**2 * muf2/ Q2)
616 tmp *= math.sqrt(4*math.pi*pdf.alphasQ2(Dmur**2*mur2))**onewgt.qcdpower
617
618 if wgtpdf == 0: #happens for nn23pdf due to wrong set in lhapdf
619 key = (self.b1*onewgt.pdgs[0], self.b2*onewgt.pdgs[1], onewgt.bjks[0],onewgt.bjks[1], muf2)
620 if dyn== -1 and Dmuf==1 and Dmur==1 and pdf==self.orig_pdf:
621 wgtpdf = onewgt.ref_wgt / tmp
622 self.pdfQ2[key] = wgtpdf
623 elif key in self.pdfQ2:
624 wgtpdf = self.pdfQ2[key]
625 else:
626 # real zero!
627 wgtpdf = 0
628
629 tmp *= wgtpdf
630 wgt += tmp
631
632 if __debug__ and dyn== -1 and Dmur==1 and Dmuf==1 and pdf==self.orig_pdf:
633 if not misc.equal(tmp, onewgt.ref_wgt, sig_fig=4):
634 misc.sprint(tmp, onewgt.ref_wgt, (tmp-onewgt.ref_wgt)/tmp)
635 misc.sprint(onewgt)
636 misc.sprint(cevent)
637 raise Exception, 'not enough agreement between stored value and computed one'
638
639
640 return wgt
641
642
643def call_systematics(args, result=sys.stdout, running=True,
644 log=lambda x:sys.stdout.write(str(x)+'\n')):
645 """calling systematics from a list of arguments"""
646
647 input, output = args[0:2]
648 opts = {}
649 for arg in args[2:]:
650 if '=' in arg:
651 key,values= arg.split('=')
652 key = key.replace('-','')
653 values = values.split(',')
654 if key == 'together':
655 if key in opts:
656 opts[key].append(tuple(values))
657 else:
658 opts[key]=[tuple(values)]
659 elif key == 'result':
660 result = open(values[0],'w')
661 elif key in ['start_event', 'stop_event']:
662 opts[key] = int(values[0])
663 elif key == 'write_banner':
664 opts[key] = banner_mod.ConfigFile.format_variable(values[0], bool, 'write_banner')
665 else:
666 if key in opts:
667 opts[key] += values
668 else:
669 opts[key] = values
670 else:
671 raise SystematicsError, "unknow argument", arg
672
673 #load run_card and extract parameter if needed.
674 if 'from_card' in opts:
675 if opts['from_card'] != ['internal']:
676 card = banner.RunCard(opts['from_card'][0])
677 else:
678 lhe = lhe_parser.EventFile(input)
679 card = banner.RunCard(banner.Banner(lhe.banner)['mgruncard'])
680 lhe.close()
681
682 if isinstance(card, banner.RunCardLO):
683 # LO case
684 opts['mur'] = [float(x) for x in card['sys_scalefact'].split()]
685 opts['muf'] = opts['mur']
686 if card['sys_alpsfact'] != 'None':
687 opts['alps'] = [float(x) for x in card['sys_alpsfact'].split()]
688 else:
689 opts['alps'] = [1.0]
690 opts['together'] = [('mur','muf','alps','dyn')]
691 pdfs = card['sys_pdf'].split('&&')
692 opts['dyn'] = [-1,1,2,3,4]
693 opts['pdf'] = []
694 for pdf in pdfs:
695 split = pdf.split()
696 if len(split)==1:
697 opts['pdf'].append('%s' %pdf)
698 else:
699 pdf,nb = split
700 for i in range(int(nb)):
701 opts['pdf'].append('%s@%s' % (pdf, i))
702 if not opts['pdf']:
703 opts['pdf'] = 'central'
704 else:
705 #NLO case
706 raise Exception
707 del opts['from_card']
708
709
710 obj = Systematics(input, output, log=log,**opts)
711 if running:
712 obj.run(result)
713 return obj
714
715if __name__ == "__main__":
716 call_systematics(sys.argv[1:])
717
718
719
720
721
722
723
724
0725
=== modified file 'tests/acceptance_tests/test_cmd_madevent.py'
--- tests/acceptance_tests/test_cmd_madevent.py 2016-08-17 16:25:19 +0000
+++ tests/acceptance_tests/test_cmd_madevent.py 2016-08-24 22:15:21 +0000
@@ -117,9 +117,10 @@
117 interface.exec_cmd('set madanalysis_path %s --no_save' % pjoin(MG5DIR, 'MadAnalysis'))117 interface.exec_cmd('set madanalysis_path %s --no_save' % pjoin(MG5DIR, 'MadAnalysis'))
118 interface.onecmd('output madevent %s -f' % self.run_dir) 118 interface.onecmd('output madevent %s -f' % self.run_dir)
119 119
120 if not os.path.exists(pjoin(interface.options['syscalc_path'],'sys_calc')):120 if os.path.exists(pjoin(interface.options['syscalc_path'],'sys_calc')):
121 print "install SysCalc"121 shutil.rmtree(interface.options['syscalc_path'])
122 interface.onecmd('install SysCalc')122 #print "install SysCalc"
123 #interface.onecmd('install SysCalc')
123 124
124 125
125 self.cmd_line = MECmd.MadEventCmdShell(me_dir=self.run_dir)126 self.cmd_line = MECmd.MadEventCmdShell(me_dir=self.run_dir)
@@ -475,10 +476,10 @@
475 # check that the html has the information476 # check that the html has the information
476 self.assertTrue('syst' in data[0].parton)477 self.assertTrue('syst' in data[0].parton)
477 # check that the code was runned correctly478 # check that the code was runned correctly
478 fsock = open('%s/Events/%s/%s_parton_syscalc.log' % \479 fsock = open('%s/Events/%s/parton_systematics.log' % \
479 (self.run_dir, data[0]['run_name'], data[0]['tag']),'r')480 (self.run_dir, data[0]['run_name']),'r')
480 text = fsock.read()481 text = fsock.read()
481 self.assertTrue(text.count('cross-section') >= 3)482 self.assertTrue(text.count('dynamical scheme') >= 3)
482 483
483 484
484 def check_pythia_output(self, run_name='run_01', syst=False):485 def check_pythia_output(self, run_name='run_01', syst=False):
@@ -488,9 +489,9 @@
488 self.assertTrue('lhe' in data[0].pythia)489 self.assertTrue('lhe' in data[0].pythia)
489 self.assertTrue('log' in data[0].pythia)490 self.assertTrue('log' in data[0].pythia)
490491
491 if syst:492# if syst:
492 # check that the html has the information493# # check that the html has the information
493 self.assertTrue('rwt' in data[0].pythia)494# self.assertTrue('rwt' in data[0].pythia)
494495
495 def check_matched_plot(self, run_name='run_01', mintime=None, tag='fermi'):496 def check_matched_plot(self, run_name='run_01', mintime=None, tag='fermi'):
496 """ """497 """ """
497498
=== modified file 'tests/input_files/run_card_matching.dat'
--- tests/input_files/run_card_matching.dat 2013-11-22 13:16:07 +0000
+++ tests/input_files/run_card_matching.dat 2016-08-24 22:15:21 +0000
@@ -234,9 +234,9 @@
234# will be use by SysCalc (if install)234# will be use by SysCalc (if install)
235#************************************** 235#**************************************
236#236#
2370.5 = sys_scalefact # Central scale factors2370.5 1 2= sys_scalefact # Central scale factors
2380.5 = sys_alpsfact # \alpha_s emission scale factors2381= sys_alpsfact # \alpha_s emission scale factors
23930 = sys_matchscale # variation of merging scale23930 = sys_matchscale # variation of merging scale
240# PDF sets and number of members (0 or none for all members).240# PDF sets and number of members (0 or none for all members).
241CT10nlo.LHgrid 1 = sys_pdf # matching scales241CT10nlo 1 = sys_pdf # matching scales
242# MSTW2008nlo68cl.LHgrid 1 = sys_pdf242# MSTW2008nlo68cl.LHgrid 1 = sys_pdf

Subscribers

People subscribed via source and target branches

to all changes: