Merge lp:~maddevelopers/mg5amcnlo/3.4.0 into lp:mg5amcnlo

Proposed by Olivier Mattelaer
Status: Merged
Merged at revision: 973
Proposed branch: lp:~maddevelopers/mg5amcnlo/3.4.0
Merge into: lp:mg5amcnlo
Diff against target: 42427 lines (+38214/-788)
156 files modified
MadSpin/decay.py (+14/-8)
MadSpin/interface_madspin.py (+31/-5)
Template/LO/Cards/pythia8_card_default.dat (+10/-8)
Template/LO/Cards/rivet_card_default.dat (+79/-0)
Template/LO/Cards/run_card.dat (+1/-0)
Template/LO/Source/run.inc (+8/-5)
Template/LO/SubProcesses/makefile (+8/-2)
Template/MadWeight/Python/Info.py (+1/-1)
Template/MadWeight/Python/clean.py (+1/-1)
Template/MadWeight/Python/expand_MadWeight.py (+1/-1)
Template/MadWeight/Python/madweight.py (+1/-1)
Template/MadWeight/Python/put_banner.py (+1/-1)
Template/MadWeight/Python/splitbanner.py (+1/-1)
Template/MadWeight/Python/tests.py (+1/-1)
Template/MadWeight/bin/madweight.py (+1/-1)
Template/MadWeight/bin/mw_options (+1/-1)
Template/MadWeight/mod_file/check_model.py (+1/-1)
Template/MadWeight/mod_file/mod_file.py (+1/-1)
Template/NLO/Cards/run_card.dat (+1/-0)
Template/NLO/Source/makefile (+12/-1)
Template/NLO/Source/run.inc (+3/-2)
Template/NLO/SubProcesses/makefile (+5/-0)
Template/NLO/SubProcesses/makefile_fks_dir (+8/-0)
Template/NLO/Utilities/NLO_Born3.py (+1/-1)
Template/NLO/Utilities/VetoPrefactors/resum_reweighter.py (+1/-1)
Template/NLO/Utilities/VetoPrefactors/virt_reweighter.py (+1/-1)
Template/NLO/bin/internal/split_jobs.py (+1/-1)
UpdateNotes.txt (+22/-3)
VERSION (+2/-3)
aloha/bin/aloha (+1/-1)
bin/compile.py (+3/-3)
bin/create_aloha_release.py (+1/-1)
bin/create_release.py (+16/-8)
bin/mg5_aMC (+7/-10)
madgraph/core/base_objects.py (+39/-1)
madgraph/interface/amcatnlo_interface.py (+1/-1)
madgraph/interface/amcatnlo_run_interface.py (+4/-2)
madgraph/interface/common_run_interface.py (+378/-59)
madgraph/interface/extended_cmd.py (+4/-4)
madgraph/interface/madevent_interface.py (+283/-40)
madgraph/interface/madgraph_interface.py (+54/-23)
madgraph/interface/reweight_interface.py (+116/-74)
madgraph/iolibs/export_fks.py (+32/-6)
madgraph/iolibs/export_v4.py (+693/-47)
madgraph/iolibs/gen_infohtml.py (+1/-1)
madgraph/iolibs/template_files/loop_optimized/check_sa.py.inc (+1/-1)
madgraph/iolibs/template_files/madevent_makefile_source (+4/-1)
madgraph/iolibs/template_files/super_auto_dsig_group_v4.inc (+1/-1)
madgraph/loop/loop_base_objects.py (+1/-0)
madgraph/loop/loop_exporters.py (+1/-1)
madgraph/madevent/gen_crossxhtml.py (+24/-2)
madgraph/madevent/gen_ximprove.py (+3/-1)
madgraph/madweight/Cards.py (+1/-1)
madgraph/madweight/MW_driver.py (+1/-1)
madgraph/madweight/MW_info.py (+1/-1)
madgraph/madweight/blob_solution.py (+1/-1)
madgraph/madweight/change_tf.py (+1/-1)
madgraph/madweight/create_param.py (+1/-1)
madgraph/madweight/create_run.py (+1/-1)
madgraph/madweight/diagram_class.py (+1/-1)
madgraph/madweight/mod_file.py (+1/-1)
madgraph/madweight/substructure_class.py (+1/-1)
madgraph/madweight/verif_event.py (+1/-1)
madgraph/madweight/write_MadWeight.py (+1/-1)
madgraph/various/banner.py (+250/-15)
madgraph/various/combine_plots.py (+1/-1)
madgraph/various/histograms.py (+1/-1)
madgraph/various/lhe_parser.py (+138/-6)
madgraph/various/misc.py (+41/-22)
madgraph/various/plot_djrs.py (+1/-1)
models/__init__.py (+1/-1)
models/check_param_card.py (+66/-41)
models/import_ufo.py (+64/-6)
models/template_files/fortran/lha_read.f (+13/-0)
models/template_files/fortran/makefile_madevent (+9/-1)
models/template_files/fortran/makefile_standalone (+11/-0)
models/template_files/fortran/testprog.f (+56/-0)
models/usermod.py (+6/-0)
models/write_param_card.py (+6/-3)
tests/acceptance_tests/test_cmd.py (+3/-0)
tests/acceptance_tests/test_cmd_amcatnlo.py (+62/-3)
tests/acceptance_tests/test_cmd_madevent.py (+142/-6)
tests/acceptance_tests/test_cmd_reweight.py (+2/-2)
tests/acceptance_tests/test_model_equivalence.py (+2/-3)
tests/input_files/IOTestsComparison/IOExportV4IOTest/export_matrix_element_v4_madevent_group/super_auto_dsig.f (+1/-1)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/%..%..%Source%MODEL%couplings.f (+24/-3)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/%..%..%Source%MODEL%mp_input.inc (+1/-1)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/dux_mumvmxg/%..%..%Source%MODEL%testprog.f (+56/-0)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%couplings.f (+24/-7)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%couplings2.f (+20/-0)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%couplings3.f (+0/-35)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%makeinc.inc (+1/-1)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%mp_couplings2.f (+26/-0)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%mp_couplings3.f (+0/-41)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%mp_input.inc (+1/-1)
tests/input_files/IOTestsComparison/long_ML_SMQCD_default/gg_wmtbx/%..%..%Source%MODEL%testprog.f (+56/-0)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/%..%..%Source%MODEL%couplings.f (+24/-3)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/%..%..%Source%MODEL%mp_input.inc (+1/-1)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/dux_mumvmxg/%..%..%Source%MODEL%testprog.f (+56/-0)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%couplings.f (+24/-7)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%couplings2.f (+20/-0)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%couplings3.f (+0/-35)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%makeinc.inc (+1/-1)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%mp_couplings2.f (+26/-0)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%mp_couplings3.f (+0/-41)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%mp_input.inc (+1/-1)
tests/input_files/IOTestsComparison/long_ML_SMQCD_optimized/gg_wmtbx/%..%..%Source%MODEL%testprog.f (+56/-0)
tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/%..%..%Source%MODEL%couplings.f (+24/-3)
tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/%..%..%Source%MODEL%mp_input.inc (+1/-1)
tests/input_files/IOTestsComparison/short_ML_SMQCD_LoopInduced/gg_hh/%..%..%Source%MODEL%testprog.f (+56/-0)
tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%couplings.f (+24/-7)
tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%couplings2.f (+12/-0)
tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%couplings3.f (+0/-27)
tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%makeinc.inc (+1/-1)
tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%mp_couplings2.f (+16/-0)
tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%mp_couplings3.f (+0/-31)
tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%mp_input.inc (+1/-1)
tests/input_files/IOTestsComparison/short_ML_SMQCD_default/gg_ttx/%..%..%Source%MODEL%testprog.f (+56/-0)
tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%couplings.f (+24/-7)
tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%couplings2.f (+12/-0)
tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%couplings3.f (+0/-27)
tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%makeinc.inc (+1/-1)
tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%mp_couplings2.f (+16/-0)
tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%mp_couplings3.f (+0/-31)
tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%mp_input.inc (+1/-1)
tests/input_files/IOTestsComparison/short_ML_SMQCD_optimized/gg_ttx/%..%..%Source%MODEL%testprog.f (+56/-0)
tests/input_files/SMEFTatNLO_running/CT_couplings.py (+12251/-0)
tests/input_files/SMEFTatNLO_running/CT_vertices.py (+8027/-0)
tests/input_files/SMEFTatNLO_running/__init__.py (+53/-0)
tests/input_files/SMEFTatNLO_running/configuration.py (+14/-0)
tests/input_files/SMEFTatNLO_running/coupling_orders.py (+21/-0)
tests/input_files/SMEFTatNLO_running/couplings.py (+2768/-0)
tests/input_files/SMEFTatNLO_running/function_library.py (+71/-0)
tests/input_files/SMEFTatNLO_running/lorentz.py (+2414/-0)
tests/input_files/SMEFTatNLO_running/object_library.py (+371/-0)
tests/input_files/SMEFTatNLO_running/oldrunning.py (+516/-0)
tests/input_files/SMEFTatNLO_running/param_card.dat (+218/-0)
tests/input_files/SMEFTatNLO_running/parameters.py (+970/-0)
tests/input_files/SMEFTatNLO_running/particles.py (+387/-0)
tests/input_files/SMEFTatNLO_running/propagators.py (+35/-0)
tests/input_files/SMEFTatNLO_running/restrict_4f.dat (+228/-0)
tests/input_files/SMEFTatNLO_running/restrict_LO.dat (+228/-0)
tests/input_files/SMEFTatNLO_running/restrict_NLO.dat (+228/-0)
tests/input_files/SMEFTatNLO_running/running.py (+516/-0)
tests/input_files/SMEFTatNLO_running/vertices.py (+4839/-0)
tests/input_files/SMEFTatNLO_running/write_param_card.py (+184/-0)
tests/input_files/rivet_contur_test.cmd (+32/-0)
tests/input_files/rivet_plot_test.cmd (+12/-0)
tests/parallel_tests/loop_sample_script.py (+1/-1)
tests/parallel_tests/sample_script.py (+1/-1)
tests/test_manager.py (+3/-1)
tests/unit_tests/core/test_base_objects.py (+45/-1)
tests/unit_tests/interface/test_madevent.py (+4/-1)
tests/unit_tests/various/test_banner.py (+8/-1)
tests/unit_tests/various/test_lhe_parser.py (+274/-0)
vendor/IREGI/src/oneloop/create.py (+1/-1)
To merge this branch: bzr merge lp:~maddevelopers/mg5amcnlo/3.4.0
Reviewer Review Type Date Requested Status
MadTeam Pending
Review via email: mp+418754@code.launchpad.net

Commit message

pass to 3.4.0

Description of the change

      SJ: Allowing to use RIVET/CONTUR from madgraph. In presence of scan, such running can also be done
          at the end of the scan. (Contribution from Sihyun Jeon)
      OM: Allow to have EFT operator to run for some special UFO model (quite restricted class of running are supported
          -- corresponding to EFT running --)
      OM: change reweighting/spinmode=onshell (from maddspin) to use the average of the matrix-element when it exists an \
order ambiguity in the matrix element like for the following process:
      p p > e+ ... z, z > e+ e-
      where permuting the momenta of the "e+" does not lead to the same
      matrix-element.
      CF: include notification when jobs are done in the unix notification center if executable notify-send is present.
          Contribution from Carlo Flore.

To post a comment you must log in.
lp:~maddevelopers/mg5amcnlo/3.4.0 updated
985. By Sihyun Jeon

rivet card changes

986. By Sihyun Jeon

test

Revision history for this message
Sihyun Jeon (shjeon) wrote :

986 seems to have overwritten Olivier's fixes but should be all fine

lp:~maddevelopers/mg5amcnlo/3.4.0 updated
987. By Sihyun Jeon

fix contur plot axis handlings, adding some logs

Revision history for this message
Sihyun Jeon (shjeon) wrote :

Hi Olivier,
good that i did some tests earlier.
Found minor glitches when making contur plots.
Added some log so that users can know which step it's going through and where the output is stored

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

Yes, don't worry (this is a case where you typically prefer to do a rebase than a merge but it does not matter).

lp:~maddevelopers/mg5amcnlo/3.4.0 updated
988. By olivier-mattelaer

fix a python3 issue

989. By olivier-mattelaer

drop support for python2.7

990. By olivier-mattelaer

update create_release

991. By olivier-mattelaer

fix bug where madspin assign decay to initial state

992. By olivier-mattelaer

Release Candidate

993. By olivier-mattelaer

avoid issue with coupling_order longer than three letter and if the line is slightly too long

994. By olivier-mattelaer

fix parsing issue for loop_filter that had [ within the python expression

995. By olivier-mattelaer

fix a line splitting issue (f77 vs f95) within orders.inc

996. By olivier-mattelaer

fixing a lower/upper case for the Running directory put in Template

997. By olivier-mattelaer

one more lower/upper case issue

998. By olivier-mattelaer

update updatenotes

999. By olivier-mattelaer

merge with LTS for second release candidate

1000. By olivier-mattelaer

fix missing option for rivet/yoda when running from madevent directory

1001. By olivier-mattelaer

smarter condition concerning the output format of the MODEL

1002. By olivier-mattelaer

merge with LTS

1003. By olivier-mattelaer

update standalone to have reweighting working for eft running of the scale + fix a madpin issue with rivet

1004. By olivier-mattelaer

fixing Davide + issue plus some tests

1005. By olivier-mattelaer

fixing some standalone issue related to running

1006. By olivier-mattelaer

update to RC3

1007. By olivier-mattelaer

update to 2.9.10 (official)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'MadSpin/decay.py'
2--- MadSpin/decay.py 2021-12-14 19:50:21 +0000
3+++ MadSpin/decay.py 2022-05-06 14:56:16 +0000
4@@ -1042,13 +1042,15 @@
5
6 decay_struct = {}
7 to_decay = collections.defaultdict(list)
8-
9+ orig_decay = collections.defaultdict(list)
10 for i, proc in enumerate(me.get('decay_chains')):
11 pid = proc.get('legs')[0].get('id')
12 to_decay[pid].append((i,proc))
13-
14-
15+ orig_decay[pid].append((i,proc))
16+
17 for leg in me.get('legs'):
18+ if not leg.get('state'): # initial state particle does not decay ...
19+ continue
20 pid = leg.get('id')
21 nb = leg.get('number')
22 if pid in to_decay:
23@@ -3415,22 +3417,24 @@
24 except IOError as error:
25 if not first:
26 raise
27+ #misc.sprint(error)
28 try:
29 external.stdin.close()
30 except Exception as error:
31- misc.sprint(error)
32+ misc.sprint(error, cond=self.nb_load<=250)
33 try:
34 external.stdout.close()
35 except Exception as error:
36- misc.sprint(error)
37+ misc.sprint(error, cond=self.nb_load<=250)
38 try:
39 external.stderr.close()
40 except Exception as error:
41- misc.sprint(error)
42+ misc.sprint(error, cond=self.nb_load<=250)
43 try:
44 external.terminate()
45- except:
46- pass
47+ except Exception as error:
48+ misc.sprint(error, cond=self.nb_load<=250)
49+
50 del self.calculator[('full',path,)]
51 return self.loadfortran(mode, path, stdin_text, first=False)
52
53@@ -3469,6 +3473,8 @@
54 path=key[1]
55 end_signal="5 0 0 0 0\n" # before closing, write down the seed
56 external.stdin.write(end_signal.encode())
57+ external.stdin.flush()
58+ external.stdout.flush()
59 ranmar_state=external.stdout.readline().decode(errors='ignore')
60 ranmar_file=pjoin(path,'ranmar_state.dat')
61 ranmar=open(ranmar_file, 'w')
62
63=== modified file 'MadSpin/interface_madspin.py'
64--- MadSpin/interface_madspin.py 2022-03-01 09:45:24 +0000
65+++ MadSpin/interface_madspin.py 2022-05-06 14:56:16 +0000
66@@ -81,6 +81,7 @@
67 self.add_param('input_format', 'auto', allowed=['auto','lhe', 'hepmc', 'lhe_no_banner'])
68 self.add_param('frame_id', 6)
69 self.add_param('global_order_coupling', '')
70+ self.add_param('identical_particle_in_prod_and_decay', 'average')
71
72 ############################################################################
73 ## Special post-processing of the options ##
74@@ -129,6 +130,11 @@
75 logger.warning('Fix order madspin fails to have the correct scale information. This can bias the results!')
76 logger.warning('Not all functionalities of MadSpin handle this mode correctly (only onshell mode so far).')
77
78+ ############################################################################
79+ def post_identical_in_prod_and_decay(self, value, change_userdefine, raiseerror):
80+ """ special handling for set fixed_order """
81+ if value not in ["crash", 'average', 'max', 'first']:
82+ raise Exception("value %s not supported for this parameter identical_in_prod_and_decay")
83
84 class MadSpinInterface(extended_cmd.Cmd):
85 """Basic interface for madspin"""
86@@ -249,6 +255,8 @@
87 self.options['nb_sigma'] = N_sigma
88 if self.options['BW_cut'] == -1:
89 self.options['BW_cut'] = float(self.banner.get_detail('run_card', 'bwcutoff'))
90+ if self.options['BW_cut'] > 25:
91+ logger.critical("value of bwcutoff set to %s from the input file. This is much too large value for Madspin and the validity of the Narrow-width-Approximation. Please ensure that you overwrite that value via \"set BW_cut X\" to a smaller value (like X=10)", self.options['BW_cut'])
92
93 if isinstance(run_card, banner.RunCardLO):
94 run_card.update_system_parameter_for_include()
95@@ -637,6 +645,8 @@
96 logger.info("Nothing to decay ...")
97 return
98
99+ if self.options['BW_cut'] > 100:
100+ raise Exception("BW_cut parameter is much too large (>100) for narrow width approximation. Please set it up to a smaller value in your madspin_card.dat")
101
102 model_line = self.banner.get('proc_card', 'full_model_line')
103
104@@ -1711,12 +1721,28 @@
105 orig_order = self.all_me[tag]['order']
106 pdir = self.all_me[tag]['pdir']
107 if pdir in self.all_f2py:
108- p = event.get_momenta(orig_order)
109- p = rwgt_interface.ReweightInterface.invert_momenta(p)
110- if event[0].color1 == 599 and event.aqcd==0:
111- return self.all_f2py[pdir](p, 0.113, 0)
112+ all_p = event.get_all_momenta(orig_order)
113+ if self.options['identical_particle_in_prod_and_decay'] == "crash" and\
114+ len(all_p)> 1:
115+ raise Exception("Ambiguous particle in production and decay. crash as requested by 'identical_particle_in_prod_and_decay'")
116+ out = 0
117+ for p in all_p:
118+ p = rwgt_interface.ReweightInterface.invert_momenta(p)
119+ if event[0].color1 == 599 and event.aqcd==0:
120+ new_value = self.all_f2py[pdir](p, 0.113, 0)
121+ else:
122+ new_value = self.all_f2py[pdir](p, event.aqcd, 0)
123+ if self.options['identical_particle_in_prod_and_decay'] == "average":
124+ out += new_value
125+ else:
126+ if abs(out)< abs(new_value):
127+ out = new_value
128+ if self.options['identical_particle_in_prod_and_decay'] == 'first':
129+ return out
130+ if self.options['identical_particle_in_prod_and_decay'] == "average":
131+ return out/len(all_p)
132 else:
133- return self.all_f2py[pdir](p, event.aqcd, 0)
134+ return out
135 else:
136 if sys.path[0] != pjoin(self.path_me, 'madspin_me', 'SubProcesses'):
137 sys.path.insert(0, pjoin(self.path_me, 'madspin_me', 'SubProcesses'))
138
139=== modified file 'Template/LO/Cards/pythia8_card_default.dat'
140--- Template/LO/Cards/pythia8_card_default.dat 2020-08-07 11:51:35 +0000
141+++ Template/LO/Cards/pythia8_card_default.dat 2022-05-06 14:56:16 +0000
142@@ -11,14 +11,16 @@
143 !
144 ! -------------------------------------------------------------------
145 ! Specify the HEPMC output of the Pythia8 shower. You can set it to:
146-! auto : MG5aMC will automatically place it the run_<i> directory
147-! autoremove: MG5aMC will automatically remove the file at the end of the run.
148-! (usefull when running with Delphes)
149+! hepmc : MG5aMC will automatically place it the run_<i> directory
150+! hepmc.gz : Same as 'hepmc', but also will compress the output file.
151+! hepmcremove : MG5aMC will automatically remove the file at the end of the run.
152+! (usefull when running with Delphes)
153+! hepmc@<hepmc_path> :
154+! User defined path where the HEPMC file must written. It will
155+! therefore not be placed in the run_<i> directory. The
156+! specified path, if not absolute, will be relative to
157+! the Event/run_<i> directory of the process output.
158 ! /dev/null : to turn off the HEPMC output.
159-! <path> : to select where the HEPMC file must written. It will
160-! therefore not be placed in the run_<i> directory. The
161-! specified path, if not absolute, will be relative to
162-! the Event/run_<i> directory of the process output.
163 ! fifo : to have MG5aMC setup the piping of the PY8 output to
164 ! analysis tools such as MadAnalysis5.
165 ! fifo@<fifo_path> :
166@@ -27,7 +29,7 @@
167 ! fifo). Note that the fifo file extension *must* be '.hepmc.fifo'.
168 ! -------------------------------------------------------------------
169 !
170-HEPMCoutput:file = auto
171+HEPMCoutput:file = hepmc.gz
172 !
173 ! --------------------------------------------------------------------
174 ! Parameters relevant only when performing MLM merging, which can be
175
176=== added file 'Template/LO/Cards/rivet_card_default.dat'
177--- Template/LO/Cards/rivet_card_default.dat 1970-01-01 00:00:00 +0000
178+++ Template/LO/Cards/rivet_card_default.dat 2022-05-06 14:56:16 +0000
179@@ -0,0 +1,79 @@
180+##################################################################
181+# #
182+# Rivet (+Contur) Card #
183+# #
184+# -------------------------------------------------------------- #
185+# #
186+# #
187+# -------------------------------------------------------------- #
188+# Rivet settings ----------------------------------------------- #
189+# -------------------------------------------------------------- #
190+#
191+analysis = [default]
192+ # ! When "[default]"
193+ # 1. Runs "MC_ELECTRONS,MC_MUONS,MC_TAUS,MC_MET,MC_JETS"
194+ # when 'run_contur=False'
195+ # 2. Runs all possible Rivet analyses with the same beam E
196+ # when 'run_contur=True'
197+ # ! When given as an array
198+ # e.g. 'analysis = [MC_GENERIC, MC_JETS, CMS_2019_I1753680]'
199+ # Runs 3 Rivet analysis written in the list above
200+ #
201+draw_rivet_plots = False
202+ # !! Can be time consuming !!
203+ # Flag to decide drawing Rivet histograms from Yoda files
204+ #
205+run_rivet_later = True
206+ # !! Meaningful only when using 'scan' mode of MadGraph !!
207+ # ! When "False"
208+ # Runs Rivet after one parameter is scanned
209+ # MadEvent->Pythia->Rivet->MadEvent->Pythia->Rivet->...
210+ # ! When "True"
211+ # Runs Rivet after all parameters are scanned
212+ # MadEvent->Pythia->MadEvent->Pythia->...->Rivet(altogether)
213+ #
214+# -------------------------------------------------------------- #
215+# Contur settigns ---------------------------------------------- #
216+# -------------------------------------------------------------- #
217+#
218+run_contur = False
219+ # Flag to decide Contur runs
220+ #
221+draw_contur_heatmap = True
222+ # !! Meaningful only when using scan mode for >=2 parameters !!
223+ # Draw heatmap using Contur
224+ #
225+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#
226+xaxis_var = x
227+ # ! type = string
228+ # xaxis variable of the heatmap (first scanning parameter)
229+ # e.g. xaxis_var = mzp # mass of Z' in param_card.dat
230+ #
231+xaxis_relvar = default
232+ # ! type = string
233+ # When "default" : Same as xaxis_var
234+ # Relative parameter defined with reference to 'xaxis_var'
235+ # Necessary when one wants to draw heatmap's xaxis with relative variable
236+ # e.g. xaxis_relvar = math.log(mzp, 10) # python library works!
237+ #
238+xaxis_label = default
239+ # ! type = string
240+ # When "default" : Same as xaxis_var
241+ # xaxis label of the heatmap
242+ # e.g. xaxis_label = "mass_{Z'}" # latex format works!
243+ #
244+xaxis_log = False
245+ # ! type = boolean
246+ # Flag to decide drawing heatmap with log scale xaxis
247+ #
248+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#
249+yaxis_var = y
250+ # Same as xaxis_var (second scanning parameter)
251+yaxis_relvar = default
252+ # Same as xaxis_relvar
253+yaxis_label = default
254+ # Same as xaxis_label
255+yaxis_log = False
256+ # Same as xaxisl_log
257+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#
258+
259
260=== modified file 'Template/LO/Cards/run_card.dat'
261--- Template/LO/Cards/run_card.dat 2022-03-01 09:45:24 +0000
262+++ Template/LO/Cards/run_card.dat 2022-05-06 14:56:16 +0000
263@@ -57,6 +57,7 @@
264 %(dsqrt_q2fact2)s = dsqrt_q2fact2 ! fixed fact scale for pdf2
265 %(dynamical_scale_choice)s = dynamical_scale_choice ! Choose one of the preselected dynamical choices
266 %(scalefact)s = scalefact ! scale factor for event-by-event scales
267+$RUNNING
268 $eva_scale
269 #*********************************************************************
270 # Type and output format
271
272=== modified file 'Template/LO/Source/run.inc'
273--- Template/LO/Source/run.inc 2021-07-29 07:25:05 +0000
274+++ Template/LO/Source/run.inc 2022-05-06 14:56:16 +0000
275@@ -4,11 +4,14 @@
276 c
277 c Scales
278 c
279- real*8 scale,scalefact,alpsfact
280- logical fixed_ren_scale,fixed_fac_scale1,fixed_fac_scale2,fixed_couplings,hmult
281- integer ickkw,nhmult,asrwgtflavor,dynamical_scale_choice,ievo_eva
282- common/to_scale/scale,scalefact,alpsfact,fixed_ren_scale,fixed_fac_scale1,fixed_fac_scale2,
283- $ fixed_couplings,ickkw,nhmult,hmult,asrwgtflavor,
284+ real*8 scale,scalefact,alpsfact,mue_ref_fixed,mue_over_ref
285+ logical fixed_ren_scale,fixed_fac_scale1, fixed_fac_scale2,fixed_couplings,hmult
286+ logical fixed_extra_scale
287+ integer ickkw,nhmult,asrwgtflavor, dynamical_scale_choice,ievo_eva
288+
289+ common/to_scale/scale,scalefact,alpsfact, mue_ref_fixed, mue_over_ref,
290+ $ fixed_ren_scale,fixed_fac_scale1, fixed_fac_scale2,
291+ $ fixed_couplings, fixed_extra_scale,ickkw,nhmult,hmult,asrwgtflavor,
292 $ dynamical_scale_choice
293 common/to_eva/ievo_eva
294 c
295
296=== modified file 'Template/LO/SubProcesses/makefile'
297--- Template/LO/SubProcesses/makefile 2021-03-17 17:12:05 +0000
298+++ Template/LO/SubProcesses/makefile 2022-05-06 14:56:16 +0000
299@@ -28,6 +28,12 @@
300
301 LIBS = $(LIBDIR)libbias.$(libext) $(LIBDIR)libdhelas.$(libext) $(LIBDIR)libdsample.$(libext) $(LIBDIR)libgeneric.$(libext) $(LIBDIR)libpdf.$(libext) $(LIBDIR)libmodel.$(libext) $(LIBDIR)libcernlib.$(libext) $(MADLOOP_LIB) $(LOOP_LIBS)
302
303+ifneq ("$(wildcard ../../Source/RUNNING)","")
304+ LINKLIBS += -lrunning
305+ LIBS += $(LIBDIR)librunning.$(libext)
306+endif
307+
308+
309 # Source files
310
311 MATRIX_HEL = $(patsubst %.f,%.o,$(wildcard matrix*_orig.f))
312@@ -52,8 +58,8 @@
313 $(PROG)_forhel: $(PROCESS) auto_dsig.o $(LIBS) $(MATRIX_HEL)
314 $(FC) -o $(PROG)_forhel $(PROCESS) $(MATRIX_HEL) $(LINKLIBS) $(LDFLAGS) $(BIASDEPENDENCIES)
315
316-gensym: $(SYMMETRY) configs.inc $(LIBDIR)libmodel.$(libext) $(LIBDIR)libgeneric.$(libext)
317- $(FC) -o gensym $(SYMMETRY) -L../../lib/ -lmodel -lgeneric -lpdf $(llhapdf) $(LDFLAGS)
318+gensym: $(SYMMETRY) configs.inc $(LIBS)
319+ $(FC) -o gensym $(SYMMETRY) -L../../lib/ $(LINKLIBS) $(LDFLAGS)
320
321 $(LIBDIR)libmodel.$(libext): ../../Cards/param_card.dat
322 cd ../../Source/MODEL; make
323
324=== modified file 'Template/MadWeight/Python/Info.py'
325--- Template/MadWeight/Python/Info.py 2019-04-17 14:39:47 +0000
326+++ Template/MadWeight/Python/Info.py 2022-05-06 14:56:16 +0000
327@@ -1,4 +1,4 @@
328-#!/usr/bin/env python
329+#!/usr/bin/env python3
330
331 from __future__ import absolute_import
332 from __future__ import print_function
333
334=== modified file 'Template/MadWeight/Python/clean.py'
335--- Template/MadWeight/Python/clean.py 2019-04-17 14:39:47 +0000
336+++ Template/MadWeight/Python/clean.py 2022-05-06 14:56:16 +0000
337@@ -1,4 +1,4 @@
338-#!/usr/bin/env python
339+#!/usr/bin/env python3
340 ##########################################################################
341 ## ##
342 ## MadWeight ##
343
344=== modified file 'Template/MadWeight/Python/expand_MadWeight.py'
345--- Template/MadWeight/Python/expand_MadWeight.py 2019-04-17 14:39:47 +0000
346+++ Template/MadWeight/Python/expand_MadWeight.py 2022-05-06 14:56:16 +0000
347@@ -1,4 +1,4 @@
348-#!/usr/bin/env python
349+#!/usr/bin/env python3
350
351 # Module
352 from __future__ import absolute_import
353
354=== modified file 'Template/MadWeight/Python/madweight.py'
355--- Template/MadWeight/Python/madweight.py 2019-04-17 14:39:47 +0000
356+++ Template/MadWeight/Python/madweight.py 2022-05-06 14:56:16 +0000
357@@ -1,4 +1,4 @@
358-#!/usr/bin/env python
359+#!/usr/bin/env python3
360
361 # idea have 2 script
362 # madweight.py -> direct submission
363
364=== modified file 'Template/MadWeight/Python/put_banner.py'
365--- Template/MadWeight/Python/put_banner.py 2019-04-17 14:39:47 +0000
366+++ Template/MadWeight/Python/put_banner.py 2022-05-06 14:56:16 +0000
367@@ -1,4 +1,4 @@
368-#!/usr/bin/env python
369+#!/usr/bin/env python3
370 ##########################################################################
371 ## ##
372 ## MG/ME/MW ##
373
374=== modified file 'Template/MadWeight/Python/splitbanner.py'
375--- Template/MadWeight/Python/splitbanner.py 2019-04-17 14:39:47 +0000
376+++ Template/MadWeight/Python/splitbanner.py 2022-05-06 14:56:16 +0000
377@@ -1,4 +1,4 @@
378-#!/usr/bin/env python
379+#!/usr/bin/env python3
380 ##########################################################################
381 ## ##
382 ## MadWeight ##
383
384=== modified file 'Template/MadWeight/Python/tests.py'
385--- Template/MadWeight/Python/tests.py 2019-04-17 14:39:47 +0000
386+++ Template/MadWeight/Python/tests.py 2022-05-06 14:56:16 +0000
387@@ -1,4 +1,4 @@
388-#!/usr/bin/env python
389+#!/usr/bin/env python3
390 ####################################################################################################
391 ####################################################################################################
392 ## ##
393
394=== modified file 'Template/MadWeight/bin/madweight.py'
395--- Template/MadWeight/bin/madweight.py 2019-04-17 14:39:47 +0000
396+++ Template/MadWeight/bin/madweight.py 2022-05-06 14:56:16 +0000
397@@ -1,4 +1,4 @@
398-#! /usr/bin/env python
399+#! /usr/bin/env python3
400 ################################################################################
401 #
402 # Copyright (c) 2011 The MadGraph Development team and Contributors
403
404=== modified file 'Template/MadWeight/bin/mw_options'
405--- Template/MadWeight/bin/mw_options 2014-01-17 15:03:48 +0000
406+++ Template/MadWeight/bin/mw_options 2022-05-06 14:56:16 +0000
407@@ -1,4 +1,4 @@
408-#! /usr/bin/env python
409+#! /usr/bin/env python3
410
411 ################################################################################
412 #
413
414=== modified file 'Template/MadWeight/mod_file/check_model.py'
415--- Template/MadWeight/mod_file/check_model.py 2019-04-17 14:39:47 +0000
416+++ Template/MadWeight/mod_file/check_model.py 2022-05-06 14:56:16 +0000
417@@ -1,4 +1,4 @@
418-#!/usr/bin/env python
419+#!/usr/bin/env python3
420
421 #test
422
423
424=== modified file 'Template/MadWeight/mod_file/mod_file.py'
425--- Template/MadWeight/mod_file/mod_file.py 2019-04-17 14:39:47 +0000
426+++ Template/MadWeight/mod_file/mod_file.py 2022-05-06 14:56:16 +0000
427@@ -1,4 +1,4 @@
428-#!/usr/bin/env python
429+#!/usr/bin/env python3
430
431 #Extension
432 from __future__ import absolute_import
433
434=== modified file 'Template/NLO/Cards/run_card.dat'
435--- Template/NLO/Cards/run_card.dat 2021-09-16 09:23:57 +0000
436+++ Template/NLO/Cards/run_card.dat 2022-05-06 14:56:16 +0000
437@@ -92,6 +92,7 @@
438 ! first are included via reweighting
439 %(mur_over_ref)s = muR_over_ref ! ratio of current muR over reference muR
440 %(muf_over_ref)s = muF_over_ref ! ratio of current muF over reference muF
441+ $RUNNING
442 #***********************************************************************
443 # Reweight variables for scale dependence and PDF uncertainty *
444 #***********************************************************************
445
446=== modified file 'Template/NLO/Source/makefile'
447--- Template/NLO/Source/makefile 2018-12-21 15:27:32 +0000
448+++ Template/NLO/Source/makefile 2022-05-06 14:56:16 +0000
449@@ -12,13 +12,24 @@
450 run_printout.o dgauss.o ranmar.o setrun.o derivative.o \
451 zerox64_cernlib.o
452
453+ifneq ("$(wildcard ./RUNNING)","")
454+ LINKLIBS += -lrunning
455+ LIBS += $(LIBDIR)librunning.$(libext)
456+endif
457+
458+
459 .f.o: ; $(FC) $(FFLAGS) -c $*.f
460 .f90.o: ; $(FC) $(FFLAGS) -c $*.f90
461
462 all: $(LIBDIR)libdhelas.a $(LIBDIR)libgeneric.a $(LIBDIR)libpdf.a \
463- $(LIBDIR)libmodel.a $(LIBDIR)libcernlib.a param_card.inc
464+ $(LIBDIR)libmodel.a $(LIBDIR)libcernlib.a param_card.inc $(LIBS)
465 rm -f PDF/*.o
466
467+
468+$(LIBDIR)librunning.$(libext): RUNNING
469+ rm -f $(LIBDIR)librunning.a
470+ cd RUNNING; make
471+
472 $(LIBDIR)libdhelas.a: DHELAS
473 rm -f $(LIBDIR)libdhelas.a
474 cd DHELAS; make
475
476=== modified file 'Template/NLO/Source/run.inc'
477--- Template/NLO/Source/run.inc 2017-10-05 13:10:51 +0000
478+++ Template/NLO/Source/run.inc 2022-05-06 14:56:16 +0000
479@@ -4,10 +4,11 @@
480 c
481 c Scales
482 c
483- real*8 scale,scalefact,ellissextonfact,alpsfact
484- logical fixed_ren_scale,fixed_fac_scale,fixed_couplings,hmult
485+ real*8 scale,scalefact,ellissextonfact,alpsfact, mue_ref_fixed, mue_over_ref
486+ logical fixed_ren_scale,fixed_fac_scale,fixed_couplings,hmult, fixed_extra_scale
487 integer ickkw,nhmult,dynamical_scale_choice
488 common/to_scale/scale,scalefact,ellissextonfact,alpsfact,fixed_ren_scale,
489+ $ mue_ref_fixed, mue_over_ref, fixed_extra_scale,
490 $ fixed_fac_scale,fixed_couplings,ickkw,nhmult,hmult,
491 $ dynamical_scale_choice
492
493
494=== modified file 'Template/NLO/SubProcesses/makefile'
495--- Template/NLO/SubProcesses/makefile 2020-07-28 09:30:35 +0000
496+++ Template/NLO/SubProcesses/makefile 2022-05-06 14:56:16 +0000
497@@ -4,6 +4,11 @@
498 LINKLIBS = -L$(LIBDIR) -lgeneric
499 LIBS = $(LIBDIR)libgeneric.a
500
501+ifneq ("$(wildcard ../../Source/RUNNING)","")
502+ LINKLIBS += -lrunning
503+ LIBS += $(LIBDIR)librunning.$(libext)
504+endif
505+
506 # Files for the read40 combiner of top drawer files
507 READ40=read40.o
508
509
510=== modified file 'Template/NLO/SubProcesses/makefile_fks_dir'
511--- Template/NLO/SubProcesses/makefile_fks_dir 2022-03-03 11:58:07 +0000
512+++ Template/NLO/SubProcesses/makefile_fks_dir 2022-05-06 14:56:16 +0000
513@@ -17,6 +17,7 @@
514 endif
515
516 NLOLIBS=-L$(LIBDIR) $(libmadloop) $(libcuttools) $(libOLP)
517+
518 # Uncomment the line below to compile with MadLoop without setting the environnement
519 # variables 'by hand'
520 # NLOLIBS= -L. -lMadLoop -L$(LIBDIR) -lcts
521@@ -24,6 +25,13 @@
522 LIBS = $(LIBDIR)libdhelas.a $(LIBDIR)libgeneric.a $(LIBDIR)libmodel.a \
523 $(LIBDIR)libpdf.a $(LIBDIR)libcernlib.a
524
525+ifneq ("$(wildcard ../../Source/RUNNING)","")
526+ LINKLIBS += -lrunning
527+ LIBS += $(LIBDIR)librunning.$(libext)
528+endif
529+
530+
531+
532 # Files for all executables
533 FILES= $(patsubst %.f,%.o,$(wildcard parton_lum_*.f)) \
534 $(patsubst %.f,%.o,$(wildcard matrix_*.f)) \
535
536=== modified file 'Template/NLO/Utilities/NLO_Born3.py'
537--- Template/NLO/Utilities/NLO_Born3.py 2020-08-21 10:29:35 +0000
538+++ Template/NLO/Utilities/NLO_Born3.py 2022-05-06 14:56:16 +0000
539@@ -1,4 +1,4 @@
540-#! /usr/bin/env python
541+#! /usr/bin/env python3
542
543 from __future__ import print_function
544 from __future__ import absolute_import
545
546=== modified file 'Template/NLO/Utilities/VetoPrefactors/resum_reweighter.py'
547--- Template/NLO/Utilities/VetoPrefactors/resum_reweighter.py 2020-02-27 11:14:44 +0000
548+++ Template/NLO/Utilities/VetoPrefactors/resum_reweighter.py 2022-05-06 14:56:16 +0000
549@@ -1,4 +1,4 @@
550-#! /usr/bin/env python
551+#! /usr/bin/env python3
552
553 ################################################################################
554 #
555
556=== modified file 'Template/NLO/Utilities/VetoPrefactors/virt_reweighter.py'
557--- Template/NLO/Utilities/VetoPrefactors/virt_reweighter.py 2020-02-27 11:14:44 +0000
558+++ Template/NLO/Utilities/VetoPrefactors/virt_reweighter.py 2022-05-06 14:56:16 +0000
559@@ -1,4 +1,4 @@
560-#! /usr/bin/env python
561+#! /usr/bin/env python3
562
563 ################################################################################
564 #
565
566=== modified file 'Template/NLO/bin/internal/split_jobs.py'
567--- Template/NLO/bin/internal/split_jobs.py 2019-04-17 14:39:47 +0000
568+++ Template/NLO/bin/internal/split_jobs.py 2022-05-06 14:56:16 +0000
569@@ -1,4 +1,4 @@
570-#!/usr/bin/env python
571+#!/usr/bin/env python3
572 # MZ, 2012-06-14
573 from __future__ import absolute_import
574 from __future__ import print_function
575
576=== modified file 'UpdateNotes.txt'
577--- UpdateNotes.txt 2022-03-18 11:10:18 +0000
578+++ UpdateNotes.txt 2022-05-06 14:56:16 +0000
579@@ -1,6 +1,21 @@
580 Update notes for MadGraph5_aMC@NLO (in reverse time order)
581
582
583+
584+3.4.0 (06/05/22)
585+ SJ: Allowing to use RIVET/CONTUR from madgraph. In presence of scan, such running can also be done
586+ at the end of the scan. (Contribution from Sihyun Jeon)
587+ OM: Allow to have EFT operator to run for some special UFO model (quite restricted class of running are supported
588+ -- corresponding to EFT running --)
589+ OM: change reweighting/spinmode=onshell (from maddspin) to use the average of the matrix-element when it exists an order ambiguity in the matrix element like for the following process:
590+ p p > e+ ... z, z > e+ e-
591+ where permuting the momenta of the "e+" does not lead to the same
592+ matrix-element.
593+ CF: include notification when jobs are done in the unix notification center if executable notify-send is present.
594+ Contribution from Carlo Flore.
595+ All: Droping the support for python2.7
596+ All: include bug fix from Long Term Stable version (2.9.10) see below
597+
598 3.3.2(18/03/22)
599 OM: (re)allow --loop_filter=True/... syntax for MC@NLO
600 RF: Fixed a bug in the phase-space generation of MadSpin,
601@@ -19,6 +34,7 @@
602 all: include all bug fix from the LTS version (2.9.7)
603 including important bug on MC@NLO and on madspin
604
605+
606 3.3.0 (12/11/21)
607 DP+HS+IT+MZ: EW corrections can be computed for tagged photons
608 OM+RR+AC: Implementation of EWA within MG5aMC (PDF for W/Z boson out of lepton beam)
609@@ -82,9 +98,13 @@
610
611 ** Long Term Stable Update **
612
613+2.9.10 (06/05/2022)
614+ OM: allow model with GC in their name to use helicity recycling
615+ OM: Forbid madspin to run with crazy value of BWcut
616+ OM: Fixing some IO issue with Madspin that was leading to a lock of the code
617+ OM: set a user interface for the set ewscheme option
618+ OM: forbid helicity recycling for model with spin2 and spin3/2 (optimization is not implemented for such case)
619
620-2.9.8 ()
621-=======
622 2.9.9 (25/02/2022)
623 OM: Fix a bug introduced in 2.9.0 for MLM generation in presence of mix EW/QCD process.
624 The bug typically leads to a crash within the systematics.py due to wrong power of alpha_s
625@@ -95,7 +115,6 @@
626 OM: Fix an issue when using "$ X" when X~ can be onshell, the phase-space symmetry factor was wrongly set.
627
628 2.9.8 (21/02/2022)
629->>>>>>> MERGE-SOURCE
630 OM: Fix in madspin where onlyhelicity mode was not working anymore
631 also allows to not specify any decay in that mode.
632 OM: Fix in multi_run mode where some meta-data where incorrectly set within the merged lhef file.
633
634=== modified file 'VERSION'
635--- VERSION 2022-03-18 11:10:18 +0000
636+++ VERSION 2022-05-06 14:56:16 +0000
637@@ -1,6 +1,5 @@
638-version = 3.3.2
639-date = 2022-03-18
640-
641+version = 3.4.0
642+date = 2022-05-06
643
644
645
646
647=== modified file 'aloha/bin/aloha'
648--- aloha/bin/aloha 2011-10-12 18:54:53 +0000
649+++ aloha/bin/aloha 2022-05-06 14:56:16 +0000
650@@ -1,4 +1,4 @@
651-#! /usr/bin/env python
652+#! /usr/bin/env python3
653
654
655 import sys
656
657=== modified file 'bin/compile.py'
658--- bin/compile.py 2021-08-14 19:22:57 +0000
659+++ bin/compile.py 2022-05-06 14:56:16 +0000
660@@ -1,4 +1,4 @@
661-#! /usr/bin/env python
662+#! /usr/bin/env python3
663 ################################################################################
664 #
665 # Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors
666@@ -295,9 +295,9 @@
667
668 def precompilation(self, debug=False):
669 if debug:
670- subprocess.call('python -m compileall .', shell=True, cwd=root_path)
671+ subprocess.call('python3 -m compileall .', shell=True, cwd=root_path)
672 else:
673- subprocess.call('python -O -m compileall .', shell=True, cwd=root_path)
674+ subprocess.call('python3 -O -m compileall .', shell=True, cwd=root_path)
675
676 if __name__ == '__main__':
677 Compile_MG5(sys.argv[1:])
678
679=== modified file 'bin/create_aloha_release.py'
680--- bin/create_aloha_release.py 2021-07-08 13:41:06 +0000
681+++ bin/create_aloha_release.py 2022-05-06 14:56:16 +0000
682@@ -1,4 +1,4 @@
683-#! /usr/bin/env python
684+#! /usr/bin/env python3
685
686 ################################################################################
687 #
688
689=== modified file 'bin/create_release.py'
690--- bin/create_release.py 2022-03-18 11:10:18 +0000
691+++ bin/create_release.py 2022-05-06 14:56:16 +0000
692@@ -129,8 +129,12 @@
693 try:
694 filetext = six.moves.urllib.request.urlopen('http://madgraph.phys.ucl.ac.be/mg5amc3_build_nb')
695 text = filetext.read().decode().split('\n')
696+ print(text)
697 web_version = int(text[0].strip())
698- last_message = int(text[1].strip())
699+ if text[1]:
700+ last_message = int(text[1].strip())
701+ else:
702+ last_message = 99
703 except (ValueError, IOError):
704 logging.warning("WARNING: impossible to detect the version number on the web")
705 answer = input('Do you want to continue anyway? (y/n)')
706@@ -225,17 +229,21 @@
707 # logging.error('Non-0 exit code %d from epydoc. Please check output.' % \
708 # status)
709 # sys.exit()
710+#if status1:
711+# logging.error('Non-0 exit code %d from epydoc. Please check output.' % \
712+# status)
713+# sys.exit()
714
715 #3. tarring the apidoc directory
716-status2 = subprocess.call(['tar', 'czf', 'doc.tgz', 'apidoc'], cwd=filepath)
717+#status2 = subprocess.call(['tar', 'czf', 'doc.tgz', 'apidoc'], cwd=filepath)
718
719-if status2:
720- logging.error('Non-0 exit code %d from tar. Please check result.' % \
721- status)
722- sys.exit()
723-else:
724+#if status2:
725+# logging.error('Non-0 exit code %d from tar. Please check result.' % \
726+# status)
727+# sys.exit()
728+#else:
729 # remove the apidoc file.
730- shutil.rmtree(os.path.join(filepath,'apidoc'))
731+# shutil.rmtree(os.path.join(filepath,'apidoc'))
732
733 # 4. Download the offline installer and other similar code
734 install_str = """
735
736=== modified file 'bin/mg5_aMC'
737--- bin/mg5_aMC 2021-02-09 14:18:31 +0000
738+++ bin/mg5_aMC 2022-05-06 14:56:16 +0000
739@@ -22,16 +22,13 @@
740 and call immediately the command line interface scripts"""
741
742 import sys
743-if sys.version_info[1] < 7:
744- if sys.version_info[0] == 2:
745- sys.exit("MadGraph5_aMC@NLO works only with python 2.7 or python 3.7 (and later).\n"+\
746- " You are currently using Python2.%s. Please use a more recent version of Python." % sys.version_info[1])
747- if sys.version_info[0] == 3:
748- sys.exit("MadGraph5_aMC@NLO works only with python 2.7 or python 3.7 (and later).\n"+\
749- " You are currently using Python 3.%i. So please upgrade your version of Python." % sys.version_info[1] +\
750- " If you have python2.7 installed you need to run the code as\n"+\
751- " python27 ./bin/mg5_aMC \n")
752-
753+if sys.version_info[0] == 2:
754+ sys.exit("MadGraph5_aMC@NLO works only with python 3.7 (and later).\n"+\
755+ " You are currently using Python2.%s. Please use a more recent version of Python." % sys.version_info[1])
756+elif sys.version_info[1] < 7:
757+ sys.exit("MadGraph5_aMC@NLO works only with python 3.7 (and later).\n"+\
758+ " You are currently using Python 3.%i. So please upgrade your version of Python." % sys.version_info[1])
759+
760 try:
761 import six
762 except ImportError:
763
764=== modified file 'madgraph/core/base_objects.py'
765--- madgraph/core/base_objects.py 2021-11-10 09:25:45 +0000
766+++ madgraph/core/base_objects.py 2022-05-06 14:56:16 +0000
767@@ -1046,8 +1046,10 @@
768 self['version_tag'] = None # position of the directory (for security)
769 self['gauge'] = [0, 1]
770 self['case_sensitive'] = True
771+ self['running_elements'] = []
772 self['allow_pickle'] = True
773 self['limitations'] = [] # MLM means that the model can sometimes have issue with MLM/default scale.
774+ # fix_scale means that the model should use fix_scale computation.
775 # attribute which might be define if needed
776 #self['name2pdg'] = {'name': pdg}
777
778@@ -1424,6 +1426,38 @@
779 return max([inter.get_WEIGHTED_order(self) for inter in \
780 self.get('interactions')])
781
782+ def get_running(self, used_parameters=None):
783+ """return a list of parameter which needs to be run together.
784+ check also that at least one requested coupling is dependent of
785+ such running
786+ """
787+
788+ correlated = []
789+
790+ for key in self["running_elements"]:
791+ for param_list in key.run_objects:
792+ names = [k.name for k in param_list]
793+ try:
794+ names.remove('aS')
795+ except Exception:
796+ pass
797+ # find all set of parameter where at least one paremeter are present
798+ this_ones = set(names)
799+ for subset in list(correlated):
800+ if any(n in subset for n in names):
801+ this_ones.update(subset)
802+ correlated.remove(subset)
803+ correlated.append(this_ones)
804+
805+ #filtering
806+ if used_parameters:
807+ for subset in list(correlated):
808+ if not any(n in subset for n in used_parameters):
809+ correlated.remove(subset)
810+
811+ return correlated
812+
813+
814
815 def check_majoranas(self):
816 """Return True if there is fermion flow violation, False otherwise"""
817@@ -1898,6 +1932,9 @@
818 for coup in list_coup:
819 coup.expr = pat.sub(replace, coup.expr)
820
821+ def get_all_spin(self):
822+ return {p.get('spin') for p in self['particles']}
823+
824 def add_param(self, new_param, depend_param):
825 """add the parameter in the list of parameter in a correct position"""
826
827@@ -1944,7 +1981,7 @@
828 depend = ('external',)
829 type = 'real'
830
831- def __init__(self, name, value, lhablock, lhacode):
832+ def __init__(self, name, value, lhablock, lhacode, scale=None):
833 """Initialize a new ParamCardVariable
834 name: name of the variable
835 value: default numerical value
836@@ -1955,6 +1992,7 @@
837 self.value = value
838 self.lhablock = lhablock
839 self.lhacode = lhacode
840+ self.scale = scale
841
842
843 #===============================================================================
844
845=== modified file 'madgraph/interface/amcatnlo_interface.py'
846--- madgraph/interface/amcatnlo_interface.py 2022-03-01 09:45:24 +0000
847+++ madgraph/interface/amcatnlo_interface.py 2022-05-06 14:56:16 +0000
848@@ -737,7 +737,7 @@
849
850 # Make a Template Copy
851 if self._export_format in ['NLO']:
852- self._curr_exporter.copy_fkstemplate()
853+ self._curr_exporter.copy_fkstemplate(self._curr_model)
854
855 # Reset _done_export, since we have new directory
856 self._done_export = False
857
858=== modified file 'madgraph/interface/amcatnlo_run_interface.py'
859--- madgraph/interface/amcatnlo_run_interface.py 2021-12-03 15:50:41 +0000
860+++ madgraph/interface/amcatnlo_run_interface.py 2022-05-06 14:56:16 +0000
861@@ -1851,7 +1851,7 @@
862 param_card_iterator.write_summary(path)
863
864 if self.allow_notification_center:
865- misc.apple_notify('Run %s finished' % os.path.basename(self.me_dir),
866+ misc.system_notify('Run %s finished' % os.path.basename(self.me_dir),
867 '%s: %s +- %s ' % (self.results.current['run_name'],
868 self.results.current['cross'],
869 self.results.current['error']))
870@@ -4543,6 +4543,9 @@
871 if not hasattr(mod, 'parameter_dict'):
872 from models import model_reader
873 mod = model_reader.ModelReader(mod)
874+ if "set EWscheme MZ_MW_alpha" in self.banner.get_detail('proc_card'):
875+ mod.change_electroweak_mode("MZ_MW_alpha")
876+ #misc.sprint(self.banner.get_detail('proc_card'))
877 mod.set_parameters_and_couplings(self.banner.param_card)
878 aewm1 = 0
879 for key in ['aEWM1', 'AEWM1', 'aEWm1', 'aewm1']:
880@@ -5595,7 +5598,6 @@
881 samples of various multiplicities without double counting, you
882 have to remove some events after showering 'by hand'. Please
883 read http://amcatnlo.cern.ch/FxFx_merging.htm for more details.""")
884-
885 if self.run_card['parton_shower'].upper() == 'PYTHIA6Q':
886 raise self.InvalidCmd("""FxFx merging does not work with Pythia6's Q-squared ordered showers.""")
887 elif self.run_card['parton_shower'].upper() != 'HERWIG6' and self.run_card['parton_shower'].upper() != 'PYTHIA8' and self.run_card['parton_shower'].upper() != 'HERWIGPP':
888
889=== modified file 'madgraph/interface/common_run_interface.py'
890--- madgraph/interface/common_run_interface.py 2021-12-03 15:40:10 +0000
891+++ madgraph/interface/common_run_interface.py 2022-05-06 14:56:16 +0000
892@@ -639,6 +639,8 @@
893 'delphes_path':'./Delphes',
894 'exrootanalysis_path':'./ExRootAnalysis',
895 'syscalc_path': './SysCalc',
896+ 'rivet_path': None,
897+ 'yoda_path': None,
898 'lhapdf': 'lhapdf-config',
899 'lhapdf_py2': None,
900 'lhapdf_py3': None,
901@@ -721,6 +723,7 @@
902
903 # Define self.proc_characteristics
904 self.get_characteristics()
905+ self.postprocessing_dirs = []
906
907 if not self.proc_characteristics['ninitial']:
908 # Get number of initial states
909@@ -1036,7 +1039,7 @@
910
911 self.ask_edit_card_static(cards, mode, plot, self.options['timeout'],
912 self.ask, first_cmd=first_cmd, from_banner=from_banner,
913- banner=banner)
914+ banner=banner, lhapdf=self.options['lhapdf'])
915
916 for c in cards:
917 if not os.path.isabs(c):
918@@ -1050,7 +1053,7 @@
919
920 @staticmethod
921 def ask_edit_card_static(cards, mode='fixed', plot=True,
922- timeout=0, ask=None, **opt):
923+ timeout=0, ask=None, lhapdf=None, **opt):
924 if not ask:
925 ask = CommonRunCmd.ask
926
927@@ -1108,7 +1111,9 @@
928 while out not in ['0', 'done']:
929 out = ask(question, '0', possible_answer, timeout=int(1.5*timeout),
930 path_msg='enter path', ask_class = AskforEditCard,
931- cards=cards, mode=mode, **opt)
932+ cards=cards, mode=mode,
933+ lhapdf=lhapdf,
934+ **opt)
935 if 'return_instance' in opt and opt['return_instance']:
936 out, cmd = out
937 if 'return_instance' in opt and opt['return_instance']:
938@@ -1134,6 +1139,7 @@
939 madweight_card.dat [MW]
940 madanalysis5_hadron_card.dat
941 madanalysis5_parton_card.dat
942+ rivet_card.dat
943
944 Please update the unit-test: test_card_type_recognition when adding
945 cards.
946@@ -1172,7 +1178,8 @@
947 '@MG5aMC skip_analysis', #MA5 --both--
948 '@MG5aMC\s*inputs\s*=\s*\*\.(?:hepmc|lhe)', #MA5 --both--
949 '@MG5aMC\s*reconstruction_name', # MA5 hadronique
950- '@MG5aMC' # MA5 hadronique
951+ '@MG5aMC', # MA5 hadronique
952+ 'run_rivet_later', # Rivet
953 ]
954
955
956@@ -1184,7 +1191,7 @@
957 return 'delphes_card.dat'
958 elif 'cen_max_tracker' in text:
959 return 'delphes_card.dat'
960- elif '@mg5amc' in text:
961+ elif any('@mg5amc' in t for t in text):
962 ma5_flag = [f[7:].strip() for f in text if f.startswith('@mg5amc')]
963 if any(f.startswith('reconstruction_name') for f in ma5_flag):
964 return 'madanalysis5_hadron_card.dat'
965@@ -1219,7 +1226,9 @@
966 elif 'fo_analysis_format' in text:
967 return 'FO_analyse_card.dat'
968 elif 'main:numberofevents' in text:
969- return 'pythia8_card.dat'
970+ return 'pythia8_card.dat'
971+ elif 'run_rivet_later' in text:
972+ return 'rivet_card.dat'
973 elif 'launch' in text:
974 # need to separate madspin/reweight.
975 # decay/set can be in both...
976@@ -1227,7 +1236,7 @@
977 return 'madspin_card.dat'
978 if 'decay' in text:
979 # need to check if this a line like "decay w+" or "set decay"
980- if re.search("(^|;)\s*decay", fulltext):
981+ if re.search("(^|;)\s*decay", fulltext, re.M):
982 return 'madspin_card.dat'
983 else:
984 return 'reweight_card.dat'
985@@ -2051,8 +2060,6 @@
986 raise self.ConfigurationError('''Can\'t load Reweight module.
987 The variable mg5_path might not be correctly configured.''')
988
989-
990-
991 if not '-from_cards' in line:
992 self.keep_cards(['reweight_card.dat'], ignore=['*'])
993 self.ask_edit_cards(['reweight_card.dat'], 'fixed', plot=False)
994@@ -2062,7 +2069,6 @@
995 if plugin and '--plugin=' not in line:
996 args.append('--plugin=%s' % plugin)
997
998-
999 if not self.force_run:
1000 # forbid this function to create an empty item in results.
1001 if self.run_name and self.results.current and self.results.current['cross'] == 0:
1002@@ -2154,7 +2160,6 @@
1003 os.path.exists(new_args[0][:-3]):
1004 to_zip = False
1005 devnull= open(os.devnull)
1006-
1007 for i in range(nb_file):
1008 new_command = list(command)
1009 if to_zip:
1010@@ -2204,7 +2209,6 @@
1011 return
1012 ########## END MULTI-CORE HANDLING #############
1013
1014-
1015 self.to_store.append('event')
1016 # forbid this function to create an empty item in results.
1017 if not self.force_run and self.results.current['cross'] == 0 and self.run_name:
1018@@ -2233,7 +2237,7 @@
1019 reweight_cmd.multicore = multicore #allow the directory creation or not
1020 reweight_cmd.import_command_file(path)
1021 reweight_cmd.do_quit('')
1022-
1023+
1024 logger.info("quit rwgt")
1025
1026
1027@@ -2521,7 +2525,7 @@
1028 pdf_path = os.path.join(sourcedir, 'PDF')
1029 # check that the name is correct, ie that the path exists
1030 if not os.path.isdir(lep_d_path):
1031- raise aMCatNLOError(('Invalid name for the dressed-lepton PDFs: %s\n' % (name)) + \
1032+ raise madgraph.aMCatNLOError(('Invalid name for the dressed-lepton PDFs: %s\n' % (name)) + \
1033 'The corresponding directory cannot be found in \n' + \
1034 'Source/PDF/lep_densities')
1035
1036@@ -2722,13 +2726,23 @@
1037 ' available when running partonic MadAnalysis5 analysis. The'+
1038 ' .lhe output of the selected run is used automatically.')
1039 input_file = pjoin(self.me_dir,'Events',self.run_name, 'unweighted_events.lhe')
1040- MA5_options['inputs'] = '%s.gz'%input_file
1041+ MA5_options['inputs'] = ['%s.gz'%input_file]
1042 if not os.path.exists('%s.gz'%input_file):
1043 if os.path.exists(input_file):
1044 misc.gzip(input_file, stdout='%s.gz' % input_file)
1045 else:
1046 logger.warning("LHE event file not found in \n%s\ns"%input_file+
1047- "Parton-level MA5 analysis will be skipped.")
1048+ "Parton-level MA5 analysis will be skipped.")
1049+ if len(args)>1:
1050+ for arg in args:
1051+ input_file = pjoin(self.me_dir,'Events',arg, 'unweighted_events.lhe')
1052+ if '%s.gz'%input_file in MA5_options['inputs']:
1053+ continue
1054+ if os.path.exists('%s.gz'%input_file):
1055+ MA5_options['inputs'].append('%s.gz'%input_file)
1056+ elif os.path.exists(input_file):
1057+ misc.gzip(input_file, stdout='%s.gz' % input_file)
1058+ MA5_options['inputs'].append('%s.gz'%input_file)
1059
1060 if mode=='hadron':
1061 # Make sure to store current results (like Pythia8 hep files)
1062@@ -2838,17 +2852,177 @@
1063 return self.list_completion(text, ['-f',
1064 '--MA5_stdout_lvl=','--input=','--no_default', '--tag='], line)
1065
1066+
1067+ def do_rivet(self, line, postprocess=False):
1068+ """launch rivet on the HepMC output"""
1069+
1070+ args = self.split_arg(line)
1071+ # Check argument's validity
1072+ if '--no_default' in args:
1073+ no_default = True
1074+ args.remove('--no_default')
1075+ else:
1076+ no_default = False
1077+
1078+ if len(args) == 0 and not self.run_name:
1079+ if self.results.lastrun:
1080+ args.insert(0, self.results.lastrun)
1081+ else:
1082+ raise self.InvalidCmd('No run name currently define. '+
1083+ 'Please add this information.')
1084+
1085+ if not hasattr(self, 'run_card'):
1086+ name = args[0]
1087+ self.set_run_name(name, tag=None, level='rivet', reload_card=True,
1088+ allow_new_tag=True)
1089+
1090+
1091+ self.configure_directory(html_opening =False)
1092+
1093+ # Update the banner with the pythia card
1094+ if not self.banner or len(self.banner) <=1:
1095+ # Here the level keyword 'pythia' must not be changed to 'pythia8'.
1096+ self.banner = banner_mod.recover_banner(self.results, 'pythia')
1097+
1098+ self.run_card = self.banner.get('run_card')
1099+
1100+ if not no_default and '-f' not in line:
1101+
1102+ self.keep_cards(['rivet_card.dat'], ignore=['*'])
1103+ self.ask_edit_cards(['rivet_card.dat'], 'fixed', plot=False)
1104+
1105+
1106+ #1 Get Rivet configurations from rivet_card.dat
1107+ if not os.path.exists(pjoin(self.me_dir, 'Cards', 'rivet_card.dat')):
1108+ if no_default:
1109+# logger.info('No rivet_card detected, so not running Rivet')
1110+ return None
1111+
1112+ files.cp(pjoin(self.me_dir, 'Cards', 'rivet_card_default.dat'),
1113+ pjoin(self.me_dir, 'Cards', 'rivet_card.dat'))
1114+ logger.info('No rivet_card found. Take the default one.')
1115+
1116+ self.update_status('running rivet', level='rivet')
1117+
1118+ rivet_config = banner_mod.RivetCard(pjoin(self.me_dir, 'Cards', 'rivet_card.dat'))
1119+ if not no_default:
1120+ rivet_config['run_rivet_later'] = False
1121+
1122+ # # Get Rivet analysis list
1123+ analysis_list = rivet_config.getAnalysisList(runcard=self.run_card)
1124+ run_analysis = ""
1125+ set_env = ""
1126+ for analysis in analysis_list:
1127+ if analysis.startswith("MC_"):
1128+ analysis = "{0}:ENERGY={1}".format(analysis, rivet_config["rivet_sqrts"])
1129+ run_analysis = "{0},{1}".format(run_analysis, analysis)
1130+ run_analysis = run_analysis.split(",", 1)[1]
1131+ if "$CONTUR_" in run_analysis:
1132+ set_env = "source {0}\n".format(pjoin(self.options['contur_path'], "contur", "data", "share", "analysis-list"))
1133+ #ATLAS_2016_I1469071 sometimes give segmentation errors and also not so safe due to neutrino truth info. Need to force remove this?
1134+ set_env = set_env + "{0}=`echo {1} | sed 's/,ATLAS_2016_I1469071//'`\n".format(run_analysis.replace("$",""), run_analysis)
1135+
1136+ # # Get weight name (merging scale)
1137+ py8_card = banner_mod.PY8Card(pjoin(self.me_dir, 'Cards', 'pythia8_card.dat'))
1138+ if rivet_config["weight_name"] == "default":
1139+ rivet_config.setWeightName(runcard=self.run_card, py8card=py8_card)
1140+
1141+ rivet_add = ""
1142+ if not (rivet_config["rivet_add"] == "default" or rivet_config["rivet_add"] == None):
1143+ rivet_add = " " + rivet_config["rivet_add"]
1144+
1145+ #2 Prepare Rivet setup environments
1146+ rivet_path = self.options['rivet_path']
1147+ yoda_path = self.options['yoda_path']
1148+ set_env = set_env + "export PATH={0}:$PATH\n".format(pjoin(rivet_path, 'bin'))
1149+ set_env = set_env + "export PATH={0}:$PATH\n".format(pjoin(yoda_path, 'bin'))
1150+ set_env = set_env + "export LD_LIBRARY_PATH={0}:{1}:$LD_LIBRARY_PATH\n".format(pjoin(rivet_path, 'lib'), pjoin(rivet_path, 'lib64'))
1151+ set_env = set_env + "export LD_LIBRARY_PATH={0}:{1}:$LD_LIBRARY_PATH\n".format(pjoin(yoda_path, 'lib'), pjoin(yoda_path, 'lib64'))
1152+ major, minor = sys.version_info[0:2]
1153+ set_env = set_env + "export PYTHONPATH={0}:{1}:$PYTHONPATH\n".format(pjoin(rivet_path, 'lib', 'python%s.%s' %(major,minor), 'site-packages'),\
1154+ pjoin(rivet_path, 'lib64', 'python%s.%s' %(major,minor), 'site-packages'))
1155+ set_env = set_env + "export PYTHONPATH={0}:{1}:$PYTHONPATH\n".format(pjoin(yoda_path, 'lib', 'python%s.%s' %(major,minor), 'site-packages'),\
1156+ pjoin(yoda_path, 'lib64', 'python%s.%s' %(major,minor), 'site-packages'))
1157+
1158+
1159+ #3 Fetch HepMC files
1160+ py8_output = py8_card["HEPMCoutput:file"]
1161+
1162+ if "@" in py8_output:
1163+ hepmc_specs = py8_output.split("@")
1164+ if os.path.isabs(hepmc_specs[1]):
1165+ hepmc_path = pjoin(hepmc_specs[1], self.run_name)
1166+ else:
1167+ hepmc_path = pjoin(self.me_dir, 'Events', hepmc_specs[1], self.run_name)
1168+ else:
1169+ hepmc_path = pjoin(self.me_dir, 'Events', self.run_name)
1170+
1171+ if "hepmc" in py8_output:
1172+ if ".gz" in py8_output:
1173+ hepmc_file = pjoin(hepmc_path, self.run_card['run_tag']+"_pythia8_events.hepmc.gz")
1174+ else:
1175+ hepmc_file = pjoin(hepmc_path, self.run_card['run_tag']+"_pythia8_events.hepmc")
1176+ elif py8_output == "fifo":
1177+ hepmc_file = pjoin(hepmc_path, "PY8.hepmc.fifo")
1178+ else:
1179+ raise MadGraph5Error("HEPMCoutput:file format unknown")
1180+
1181+ #4 Write Rivet lines
1182+ shell = 'bash' if misc.get_shell_type() in ['bash',None] else 'tcsh'
1183+
1184+ yoda_file = pjoin(self.me_dir, 'Events', self.run_name, "rivet_result.yoda")
1185+ run_rivet = pjoin(rivet_path, "bin", "rivet") + " --skip-weights -a " + run_analysis + " -o " + yoda_file + " " + hepmc_file + rivet_add
1186+
1187+ wrapper = open(pjoin(self.me_dir, 'Events', self.run_name, "run_rivet.sh"), "w")
1188+ wrapper.write("#!{0}\n{1}\n".format(misc.which(shell), set_env))
1189+ wrapper.write(sys.executable + " {0} &> {1}\n".format(run_rivet, pjoin(self.me_dir, 'Events', self.run_name, "rivet.log")))
1190+ if rivet_config['draw_rivet_plots']:
1191+ draw_rivet = "{0} {1} -o {2}".format(pjoin(rivet_path, "bin", "rivet-mkhtml"), pjoin(self.me_dir, 'Events', self.run_name, "rivet_result.yoda"), pjoin(self.me_dir, 'Events', self.run_name, 'rivet-plots'))
1192+ wrapper.write(sys.executable + " " + draw_rivet + " &> {0}".format(pjoin(self.me_dir, 'Events', self.run_name, "rivet-plots.log")))
1193+ logger.info("Rivet plots will be stored in {0}".format(pjoin(self.me_dir, 'Events', self.run_name, 'rivet-plots')))
1194+# rivet_config["run_rivet_later"] =True
1195+
1196+ if py8_output == "fifo":
1197+ wrapper.write("\nrm {0}\n".format(hepmc_file))
1198+ wrapper.close()
1199+
1200+ if ("remove" in py8_output) or ("fifo" in py8_output): # For hepmcremove and fifo, should not be postprocessed
1201+ rivet_config["run_rivet_later"] = False
1202+
1203+ postprocess_RIVET = rivet_config["run_rivet_later"]
1204+ postprocess_CONTUR = rivet_config["run_contur"]
1205+
1206+ os.system("chmod +x {0}".format(pjoin(self.me_dir, 'Events', self.run_name, "run_rivet.sh")))
1207+
1208+ #5 decide how to run Rivet
1209+ if postprocess: #inside postprocessing functions, no need to run, just need to return rivet configurations
1210+ self.update_status('rivet done', level='rivet')
1211+ return [rivet_config, postprocess_RIVET, postprocess_CONTUR]
1212+ else:
1213+ if postprocess_RIVET:
1214+ logger.info("Skipping Rivet for now, passing it to postprocessor")
1215+ self.update_status('rivet done', level='rivet')
1216+ self.postprocessing_dirs.append(self.run_name)
1217+ return
1218+ else:
1219+ logger.info("Running Rivet with {0}".format(hepmc_file))
1220+ misc.call([pjoin('Events', self.run_name, "run_rivet.sh")], cwd=self.me_dir)
1221+ self.update_status('rivet done', level='rivet')
1222+ return
1223+
1224+
1225 def do_madanalysis5_hadron(self, line):
1226 """launch MadAnalysis5 at the hadron level."""
1227 return self.run_madanalysis5(line,mode='hadron')
1228
1229+
1230+
1231 def run_madanalysis5(self, line, mode='parton'):
1232 """launch MadAnalysis5 at the parton level or at the hadron level with
1233 a specific command line."""
1234
1235 # Check argument's validity
1236 args = self.split_arg(line)
1237-
1238 if '--no_default' in args:
1239 no_default = True
1240 args.remove('--no_default')
1241@@ -2914,12 +3088,12 @@
1242 run_tag = self.run_tag)
1243
1244 # Here's how to print the MA5 commands generated by MG5aMC
1245- if __debug__:
1246- for MA5_runtag, MA5_cmds in MA5_cmds_list:
1247- misc.sprint('****************************************')
1248- misc.sprint('* Commands for MA5 runtag %s:'%MA5_runtag)
1249- misc.sprint('\n'+('\n'.join('* %s'%cmd for cmd in MA5_cmds)))
1250- misc.sprint('****************************************')
1251+ #if __debug__:
1252+ # for MA5_runtag, MA5_cmds in MA5_cmds_list:
1253+ # misc.sprint('****************************************')
1254+ # misc.sprint('* Commands for MA5 runtag %s:'%MA5_runtag)
1255+ # misc.sprint('\n'+('\n'.join('* %s'%cmd for cmd in MA5_cmds)))
1256+ # misc.sprint('****************************************')
1257
1258 self.update_status('\033[92mRunning MadAnalysis5 [arXiv:1206.1599]\033[0m',
1259 level='madanalysis5_%s'%mode)
1260@@ -3514,7 +3688,8 @@
1261 the cards afterwards, you can type \"compute_wdiths\".''')
1262
1263 card = param_card_mod.ParamCard(path)
1264- if dependent:
1265+ if dependent:
1266+
1267 AskforEditCard.update_dependent(interface, interface.me_dir, card, path, timer=20)
1268
1269 for param in card['decay']:
1270@@ -3699,7 +3874,8 @@
1271 'delphes_trigger.dat', 'madspin_card.dat', 'shower_card.dat',
1272 'reweight_card.dat','pythia8_card.dat',
1273 'madanalysis5_parton_card.dat','madanalysis5_hadron_card.dat',
1274- 'plot_card.dat']
1275+ 'plot_card.dat',
1276+ 'rivet_card.dat']
1277
1278 cards_path = pjoin(self.me_dir,'Cards')
1279 for card in check_card:
1280@@ -4429,7 +4605,7 @@
1281 wwwpath = "http://lhapdfsets.web.cern.ch/lhapdfsets/current/%s.tar.gz" % filename
1282 misc.wget(wwwpath, pjoin(pdfsets_dir, '%s.tar.gz' %filename))
1283 misc.call(['tar', '-xzpvf', '%s.tar.gz' %filename],
1284- cwd=pdfsets_dir)
1285+ cwd=pdfsets_dir)
1286
1287 if os.path.exists(pjoin(pdfsets_dir, filename)) or \
1288 os.path.isdir(pjoin(pdfsets_dir, filename)):
1289@@ -4627,16 +4803,16 @@
1290 """
1291
1292 all_card_name = ['param_card', 'run_card', 'pythia_card', 'pythia8_card',
1293- 'madweight_card', 'MadLoopParams', 'shower_card']
1294+ 'madweight_card', 'MadLoopParams', 'shower_card', 'rivet_card']
1295 to_init_card = ['param', 'run', 'madweight', 'madloop',
1296- 'shower', 'pythia8','delphes','madspin']
1297+ 'shower', 'pythia8','delphes','madspin', 'rivet']
1298 special_shortcut = {}
1299 special_shortcut_help = {}
1300
1301 integer_bias = 1 # integer corresponding to the first entry in self.cards
1302
1303 PY8Card_class = banner_mod.PY8Card
1304-
1305+
1306 def load_default(self):
1307 """ define all default variable. No load of card here.
1308 This allow to subclass this class and just change init and still have
1309@@ -4657,6 +4833,7 @@
1310 self.has_shower = False
1311 self.has_PY8 = False
1312 self.has_delphes = False
1313+ self.has_rivet = False
1314 self.paths = {}
1315 self.update_block = []
1316
1317@@ -4690,6 +4867,8 @@
1318 self.paths['madspin'] = pjoin(self.me_dir,'Cards/madspin_card.dat')
1319 self.paths['reweight'] = pjoin(self.me_dir,'Cards','reweight_card.dat')
1320 self.paths['delphes'] = pjoin(self.me_dir,'Cards','delphes_card.dat')
1321+ self.paths['rivet_default'] = pjoin(self.me_dir,'Cards','rivet_card_default.dat')
1322+ self.paths['rivet'] = pjoin(self.me_dir,'Cards','rivet_card.dat')
1323 self.paths['plot'] = pjoin(self.me_dir,'Cards','plot_card.dat')
1324 self.paths['plot_default'] = pjoin(self.me_dir,'Cards','plot_card_default.dat')
1325 self.paths['madanalysis5_parton'] = pjoin(self.me_dir,'Cards','madanalysis5_parton_card.dat')
1326@@ -4701,9 +4880,10 @@
1327
1328
1329
1330- def __init__(self, question, cards=[], from_banner=None, banner=None, mode='auto', *args, **opt):
1331-
1332-
1333+ def __init__(self, question, cards=[], from_banner=None, banner=None, mode='auto',
1334+ lhapdf=None, *args, **opt):
1335+
1336+ self.lhapdf = lhapdf
1337 self.load_default()
1338 self.define_paths(**opt)
1339 self.last_editline_pos = 0
1340@@ -5001,7 +5181,28 @@
1341 'mpi' : 'syntax: set mpi value: allow to turn mpi in Pythia8 on/off',
1342 })
1343 return []
1344-
1345+
1346+ def init_rivet(self, cards):
1347+
1348+ self.has_rivet = False
1349+ if not self.get_path('rivet', cards):
1350+ return []
1351+ self.has_rivet = True
1352+
1353+ self.special_shortcut.update({
1354+ 'fast_rivet': ([], ['rivet_card run_rivet_later True', 'rivet_card draw_rivet_plots False', 'pythia8_card HEPMCoutput:file hepmc', 'partonlevel:mpi = off'])
1355+ })
1356+ self.special_shortcut_help.update({
1357+ 'fast_rivet' : 'Fastest way to run multiple Rivet runs when scanning. Does NOT compress the HepMC files so enough storage should be guaranteed!'
1358+ })
1359+
1360+ self.rivet_card = banner_mod.RivetCard(self.paths['rivet'])
1361+ self.rivet_card_default = banner_mod.RivetCard()
1362+
1363+ self.rivet_vars = [k.lower() for k in self.rivet_card.keys()]
1364+
1365+ return []
1366+
1367 def init_madspin(self, cards):
1368
1369 if not self.get_path('madspin', cards):
1370@@ -5283,7 +5484,9 @@
1371 allowed['pythia8_card'] = ''
1372 if self.has_delphes:
1373 allowed['delphes_card'] = ''
1374-
1375+ if self.has_rivet:
1376+ allowed['rivet_card'] = ''
1377+
1378 elif len(args) == 2:
1379 if args[1] == 'run_card':
1380 allowed = {'run_card':'default'}
1381@@ -5305,6 +5508,8 @@
1382 allowed = {'shower_card':'default'}
1383 elif args[1] == 'delphes_card':
1384 allowed = {'delphes_card':'default'}
1385+ elif args[1] == 'rivet_card':
1386+ allowed = {'rivet_card':'default'}
1387 else:
1388 allowed = {'value':''}
1389
1390@@ -5312,7 +5517,7 @@
1391 start = 1
1392 if args[1] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card',
1393 'MadLoop_card','pythia8_card','delphes_card','plot_card',
1394- 'madanalysis5_parton_card','madanalysis5_hadron_card']:
1395+ 'madanalysis5_parton_card','madanalysis5_hadron_card', 'rivet_card']:
1396 start = 2
1397
1398 if args[-1] in list(self.pname2block.keys()):
1399@@ -5347,7 +5552,9 @@
1400 categories.append('pythia8_card')
1401 if self.has_delphes:
1402 categories.append('delphes_card')
1403-
1404+ if self.has_rivet:
1405+ categories.append('rivet_card')
1406+
1407 possibilities['category of parameter (optional)'] = \
1408 self.list_completion(text, categories)
1409
1410@@ -5386,6 +5593,12 @@
1411 opts.append('default')
1412 possibilities['Pythia8 Parameter'] = self.list_completion(text, opts)
1413
1414+ if 'rivet_card' in list(allowed.keys()):
1415+ opts = self.rivet_vars
1416+ if allowed['rivet_card'] == 'default':
1417+ opts.append('default')
1418+ possibilities['Rivet Card'] = self.list_completion(text, opts)
1419+
1420 if 'shower_card' in list(allowed.keys()):
1421 opts = self.shower_vars + [k for k in self.shower_card.keys() if k !='comment']
1422 if allowed['shower_card'] == 'default':
1423@@ -5398,7 +5611,7 @@
1424 possibilities['Delphes Card'] = self.list_completion(text, opts)
1425
1426 if 'value' in list(allowed.keys()):
1427- opts = ['default']
1428+ opts = ['default', 'scale']
1429 if 'decay' in args:
1430 opts.append('Auto')
1431 opts.append('Auto@NLO')
1432@@ -5443,7 +5656,7 @@
1433
1434 if not ids:
1435 if tuple([int(i) for i in allowed['block'][1]]) in block:
1436- opts = ['default']
1437+ opts = ['default', 'scale']
1438 if allowed['block'][0] == 'decay':
1439 opts.append('Auto')
1440 opts.append('Auto@NLO')
1441@@ -5599,7 +5812,13 @@
1442 logger.warning('Invalid Command: No Pythia8 card defined.')
1443 return
1444 args[0] = 'pythia8_card'
1445-
1446+
1447+ if args[0] == "rivet_card":
1448+ if not self.has_rivet:
1449+ logger.warning('Invalid Command: No Rivet card defined.')
1450+ return
1451+ args[0] = 'rivet_card'
1452+
1453 if args[0] == 'delphes_card':
1454 if not self.has_delphes:
1455 logger.warning('Invalid Command: No Delphes card defined.')
1456@@ -5614,9 +5833,9 @@
1457 files.cp(pjoin(self.me_dir,'Cards', 'delphes_card_CMS.dat'),
1458 pjoin(self.me_dir,'Cards', 'delphes_card.dat'))
1459 return
1460-
1461+
1462 if args[0] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card',
1463- 'delphes_card','madanalysis5_hadron_card','madanalysis5_parton_card']:
1464+ 'delphes_card','madanalysis5_hadron_card','madanalysis5_parton_card','rivet_card']:
1465
1466 if args[1] == 'default':
1467 logger.info('replace %s by the default card' % args[0],'$MG:BOLD')
1468@@ -5662,6 +5881,7 @@
1469 if len(args) < 3:
1470 logger.warning('Invalid set command: %s (not enough arguments)' % line)
1471 return
1472+
1473 elif args[0] in ['madspin_card']:
1474 if args[1] == 'default':
1475 logger.info('replace madspin_card.dat by the default card','$MG:BOLD')
1476@@ -5737,6 +5957,10 @@
1477 logger.warning('%s is not part of block "%s" but "%s". please correct.' %
1478 (args[start+1], args[start], bname))
1479 return
1480+ elif args[start+1] == 'scale':
1481+ self.modified_card.add('param')
1482+ self.setP(args[start], None, args[-1])
1483+ return
1484 else:
1485 try:
1486 key = tuple([int(i) for i in args[start+1:-1]])
1487@@ -5912,7 +6136,24 @@
1488 self.PY8Card.write(pjoin(self.me_dir,'Cards','pythia8_card.dat'),
1489 pjoin(self.me_dir,'Cards','pythia8_card_default.dat'),
1490 print_only_visible=True)
1491-
1492+
1493+ # Rivet Parameter -----------------------------------------------------
1494+ elif self.has_rivet and (card in ['', 'rivet_card'])\
1495+ and args[start].lower() in [k.lower() for k in self.rivet_card.keys()]:
1496+
1497+ if args[start] in self.conflict and card == '':
1498+ text = 'ambiguous name (present in more than one card). Please specify which card to edit'
1499+ logger.warning(text)
1500+ return
1501+ if args[start+1] == 'default':
1502+ value = self.rivet_card_default[args[start]]
1503+ default = True
1504+ else:
1505+ value = args[start+1]
1506+ default = False
1507+ self.setRivet(args[start], value, default=default)
1508+ self.rivet_card.write(self.paths['rivet'], self.paths['rivet_default'])
1509+
1510 #INVALID --------------------------------------------------------------
1511 else:
1512 logger.warning('invalid set command %s ' % line)
1513@@ -5988,6 +6229,16 @@
1514 if default and name.lower() in self.PY8Card.user_set:
1515 self.PY8Card.user_set.remove(name.lower())
1516
1517+ def setRivet(self, name, value, default):
1518+ try:
1519+ self.rivet_card.set(name, value, user=True)
1520+ except Exception as error:
1521+ logger.warning("Fail to change parameter. Please Retry. Reason: %s." % error)
1522+ return
1523+ logger.info('modify parameter %s of the rivet_card.dat to %s' % (name, value), '$MG:BOLD')
1524+ if default and name.lower() in self.rivet_card.user_set:
1525+ self.rivet_card.user_set.remove(name.lower())
1526+
1527 def setP(self, block, lhaid, value):
1528 if isinstance(value, str):
1529 value = value.lower()
1530@@ -6021,9 +6272,14 @@
1531 except ValueError:
1532 logger.warning('Invalid input: \'%s\' not valid intput.'% value)
1533
1534- logger.info('modify param_card information BLOCK %s with id %s set to %s' %\
1535- (block, lhaid, value), '$MG:BOLD')
1536- self.param_card[block].param_dict[lhaid].value = value
1537+ if lhaid:
1538+ logger.info('modify param_card information BLOCK %s with id %s set to %s' %\
1539+ (block, lhaid, value), '$MG:BOLD')
1540+ self.param_card[block].param_dict[lhaid].value = value
1541+ else:
1542+ logger.info('modify param_card information scale of BLOCK %s set to %s' %\
1543+ (block, value), '$MG:BOLD')
1544+ self.param_card[block].scale = value
1545
1546 def check_card_consistency(self):
1547 """This is run on quitting the class. Apply here all the self-consistency
1548@@ -6032,7 +6288,7 @@
1549 ########################################################################
1550 # LO specific check
1551 ########################################################################
1552- if isinstance(self.run_card,banner_mod.RunCardLO):
1553+ if self.run_card and isinstance(self.run_card,banner_mod.RunCardLO):
1554
1555 proc_charac = self.mother_interface.proc_characteristics
1556 if proc_charac['grouped_matrix'] and \
1557@@ -6097,8 +6353,19 @@
1558 raise InvalidCmd("Your model is identified as not fully supported within MG5aMC.\n" +\
1559 "As your process seems to be impacted by the issue,\n" +\
1560 "You can NOT run with MLM matching/merging. Please check if merging outside MG5aMC are suitable or refrain to use merging with this model")
1561-
1562- #
1563+
1564+ if 'fix_scale' in proc_charac['limitations']:
1565+ if not self.run_card['fixed_fac_scale'] or not self.run_card['fixed_ren_scale']:
1566+ raise InvalidCmd("Your model is identified as having not SM running of the strong coupling.\n"+\
1567+ "Therefore you can not perform scale running computation.")
1568+ if self.run_card['ickkw']:
1569+ raise InvalidCmd("Your model is identified as having not SM running of the strong coupling.\n"+\
1570+ "Therefore you can not perform MLM merging with this model.")
1571+
1572+ if self.run_card['lpp1'] !=0 or self.run_card['lpp2'] !=0:
1573+ logger.critical("Your model is identified as having not SM running of the strong coupling.\n"+\
1574+ "PLEASE check carefully the value use for alphas in the internal log.")
1575+
1576 if not 'sde_strategy' in self.run_card.user_set:
1577 if proc_charac['single_color']:
1578 self.run_card['SDE_strategy'] = 2
1579@@ -6128,7 +6395,7 @@
1580 # NLO specific check
1581 ########################################################################
1582 # For NLO run forbid any pdg specific cut on massless particle
1583- if isinstance(self.run_card,banner_mod.RunCardNLO):
1584+ if self.run_card and isinstance(self.run_card,banner_mod.RunCardNLO):
1585
1586 try:
1587 proc_charac = self.mother_interface.proc_characteristics
1588@@ -6139,7 +6406,11 @@
1589 if self.run_card['ickkw']:
1590 raise Exception( "Your model is identified as not fully supported within MG5aMC.\n" +\
1591 "You can NOT run with FxFx/UnLOPS matching/merging. Please check if merging outside MG5aMC are suitable or refrain to use merging with this model")
1592-
1593+
1594+ if 'fix_scale' in proc_charac['limitations']:
1595+ raise Exception( "Your model is identified as not fully supported within MG5aMC.\n" +\
1596+ "Your model does not have a SM like running of the strong coupling.")
1597+
1598 for pdg in set(list(self.run_card['pt_min_pdg'].keys())+list(self.run_card['pt_max_pdg'].keys())+
1599 list(self.run_card['mxx_min_pdg'].keys())):
1600
1601@@ -6191,12 +6462,12 @@
1602 # this can be dressed lepton or photon-flux
1603 if proc_charac['pdg_initial1'] in [[11],[-11]] and proc_charac['pdg_initial2'] in [[11],[-11]]:
1604 if self['pdlabel'] not in self.allowed_lep_densities[(-11,11)]:
1605- raise InvalidRunCard('pdlabel %s not allowed for dressed-lepton collisions' % self['pdlabel'])
1606+ raise banner_mod.InvalidRunCard('pdlabel %s not allowed for dressed-lepton collisions' % self['pdlabel'])
1607 elif abs(self.run_card['lpp1']) == abs(self.run_card['lpp2']) == 4:
1608 # this can be dressed lepton or photon-flux
1609 if proc_charac['pdg_initial1'] in [[13],[-13]] and proc_charac['pdg_initial2'] in [[13],[-13]]:
1610 if self['pdlabel'] not in self.allowed_lep_densities[(-13,13)]:
1611- raise InvalidRunCard('pdlabel %s not allowed for dressed-lepton collisions' % self['pdlabel'])
1612+ raise banner_mod.InvalidRunCard('pdlabel %s not allowed for dressed-lepton collisions' % self['pdlabel'])
1613
1614
1615
1616@@ -6342,8 +6613,9 @@
1617
1618 # calling the routine doing the work
1619 self.update_dependent(self.mother_interface, self.me_dir, self.param_card,
1620- self.paths['param'], timer)
1621-
1622+ self.paths['param'], timer, run_card=self.run_card,
1623+ lhapdfconfig=self.lhapdf)
1624+
1625 elif args[0] == 'missing':
1626 self.update_missing()
1627 return
1628@@ -6401,7 +6673,8 @@
1629 self.param_card.write(self.paths['param'])
1630
1631 @staticmethod
1632- def update_dependent(mecmd, me_dir, param_card, path ,timer=0):
1633+ def update_dependent(mecmd, me_dir, param_card, path ,timer=0, run_card=None,
1634+ lhapdfconfig=None):
1635 """static method which can also be called from outside the class
1636 usefull in presence of scan.
1637 return if the param_card was updated or not
1638@@ -6410,8 +6683,12 @@
1639 if not param_card:
1640 return False
1641
1642+
1643 logger.info('Update the dependent parameter of the param_card.dat')
1644- modify = True
1645+
1646+
1647+
1648+ modify = False
1649 class TimeOutError(Exception):
1650 pass
1651 def handle_alarm(signum, frame):
1652@@ -6422,6 +6699,44 @@
1653 log_level=30
1654 else:
1655 log_level=20
1656+
1657+ if run_card:
1658+ as_for_pdf = {'cteq6_m': 0.118,
1659+ 'cteq6_d': 0.118,
1660+ 'cteq6_l': 0.118,
1661+ 'cteq6l1': 0.129783,
1662+ 'nn23lo': 0.119,
1663+ 'nn23lo1': 0.130,
1664+ 'nn23nlo': 0.119,
1665+ 'ct14q00': 0.118,
1666+ 'ct14q07': 0.118,
1667+ 'ct14q14': 0.118,
1668+ 'ct14q21':0.118}
1669+
1670+ pdlabel = run_card['pdlabel']
1671+ if pdlabel == 'mixed':
1672+ pdlabel1 = run_card['pdlabel1']
1673+ if pdlabel1 == 'lhapdf' or pdlabel1 in as_for_pdf:
1674+ pdlabel = pdlabel1
1675+
1676+ if pdlabel == 'lhapdf':
1677+ lhapdf = misc.import_python_lhapdf(lhapdfconfig)
1678+ if lhapdf:
1679+ old_value = param_card.get('sminputs').get((3,)).value
1680+ lhapdf.setVerbosity(0)
1681+ pdf = lhapdf.mkPDF(run_card['lhaid'])
1682+ new_value = pdf.alphasQ(91.1876)
1683+ param_card.get('sminputs').get((3,)).value = new_value
1684+ logger.log(log_level, "update the strong coupling value (alpha_s) to the value from the pdf selected: %s", new_value)
1685+ modify = True
1686+ elif pdlabel in as_for_pdf:
1687+ old_value = param_card.get('sminputs').get((3,)).value
1688+ new_value = as_for_pdf[pdlabel]
1689+ if old_value != new_value:
1690+ param_card.get('sminputs').get((3,)).value = as_for_pdf[pdlabel]
1691+ logger.log(log_level, "update the strong coupling value (alpha_s) to the value from the pdf selected: %s", as_for_pdf[pdlabel])
1692+ modify = True
1693+
1694 # Try to load the model in the limited amount of time allowed
1695 try:
1696 model = mecmd.get_model()
1697@@ -6435,18 +6750,21 @@
1698 logger.debug(str(error))
1699 logger.warning('Failed to update dependent parameter. This might create trouble for external program (like MadSpin/shower/...)')
1700 signal.alarm(0)
1701+ modify=False
1702 else:
1703 restrict_card = pjoin(me_dir,'Source','MODEL','param_card_rule.dat')
1704 if not os.path.exists(restrict_card):
1705 restrict_card = None
1706 #restrict_card = None
1707 if model:
1708- modify = param_card.update_dependent(model, restrict_card, log_level)
1709- if modify and path:
1710- param_card.write(path)
1711+ restrict_modify = param_card.update_dependent(model, restrict_card, log_level)
1712+ if restrict_modify:
1713+ modify = True
1714 else:
1715 logger.warning('missing MG5aMC code. Fail to update dependent parameter. This might create trouble for program like MadSpin/shower/...')
1716
1717+ if modify and path:
1718+ param_card.write(path)
1719 if log_level==20:
1720 logger.info('param_card up to date.')
1721
1722@@ -7328,6 +7646,7 @@
1723 logger.info("write scan results in %s" % path ,'$MG:BOLD')
1724 order = summaryorder(obj)()
1725 param_card_iterator.write_summary(path, order=order)
1726+
1727 return new_fct
1728 return decorator
1729
1730
1731=== modified file 'madgraph/interface/extended_cmd.py'
1732--- madgraph/interface/extended_cmd.py 2021-11-08 08:25:41 +0000
1733+++ madgraph/interface/extended_cmd.py 2022-05-06 14:56:16 +0000
1734@@ -1510,20 +1510,20 @@
1735 stop = self.nice_user_error(error, line)
1736
1737 if self.allow_notification_center:
1738- misc.apple_notify('Run %sfailed' % me_dir,
1739+ misc.system_notify('Run %sfailed' % me_dir,
1740 'Invalid Command: %s' % error.__class__.__name__)
1741
1742 except self.ConfigurationError as error:
1743 stop = self.nice_config_error(error, line)
1744 if self.allow_notification_center:
1745- misc.apple_notify('Run %sfailed' % me_dir,
1746+ misc.system_notify('Run %sfailed' % me_dir,
1747 'Configuration error')
1748 except Exception as error:
1749 stop = self.nice_error_handling(error, line)
1750 if self.mother:
1751 self.do_quit('')
1752 if self.allow_notification_center:
1753- misc.apple_notify('Run %sfailed' % me_dir,
1754+ misc.system_notify('Run %sfailed' % me_dir,
1755 'Exception: %s' % error.__class__.__name__)
1756 except KeyboardInterrupt as error:
1757 self.stop_on_keyboard_stop()
1758@@ -2838,7 +2838,7 @@
1759 rules = dict([(k, None) for k in self.switch])
1760 rules.update(getattr(self, 'consistency_%s' % key2)(value, tmp_switch))
1761 else:
1762- rules = self.check_consistency_with_all(key2)
1763+ rules = self.check_consistency_with_all(key2, value2)
1764
1765 for key, replacement in rules.items():
1766 if replacement:
1767
1768=== modified file 'madgraph/interface/madevent_interface.py'
1769--- madgraph/interface/madevent_interface.py 2021-12-03 15:40:10 +0000
1770+++ madgraph/interface/madevent_interface.py 2022-05-06 14:56:16 +0000
1771@@ -338,7 +338,14 @@
1772 self.run_options_help([('-f','answer all question by default'),
1773 ('--tag=', 'define the tag for the pythia8 run'),
1774 ('--no_default', 'not run if pythia8_card not present')])
1775-
1776+
1777+ def help_rivet(self):
1778+ logger.info("syntax: rivet [RUN] [--run_options]")
1779+ logger.info("-- run rivet on RUN (current one by default)")
1780+ self.run_options_help([('-f','answer all question by default'),
1781+ ('--tag=', 'define the tag for the rivet run'),
1782+ ('--no_default', 'not run if rivet_card not present')])
1783+
1784 def help_banner_run(self):
1785 logger.info("syntax: banner_run Path|RUN [--run_options]")
1786 logger.info("-- Reproduce a run following a given banner")
1787@@ -513,7 +520,6 @@
1788 def check_available_module(self, options):
1789
1790 self.available_module = set()
1791-
1792 if options['pythia-pgs_path']:
1793 self.available_module.add('PY6')
1794 self.available_module.add('PGS')
1795@@ -530,6 +536,12 @@
1796 self.available_module.add('Delphes')
1797 else:
1798 logger.warning("Delphes program installed but no parton shower module detected.\n Please install pythia8")
1799+ if options['rivet_path']:
1800+ if 'PY8' in self.available_module:
1801+ self.available_module.add('Rivet')
1802+ else:
1803+ logger.warning("Rivet program installed but no parton shower with hepmc output detected.\n Please install pythia8")
1804+
1805 if not MADEVENT or ('mg5_path' in options and options['mg5_path']):
1806 self.available_module.add('MadSpin')
1807 if misc.has_f2py() or options['f2py_compiler']:
1808@@ -626,6 +638,9 @@
1809 return 'OFF'
1810
1811 return None
1812+
1813+
1814+
1815 #
1816 # HANDLING DETECTOR
1817 #
1818@@ -740,7 +755,9 @@
1819 if 'MA4' in self.available_module:
1820 self.allowed_analysis.append('MadAnalysis4')
1821 if 'MA5' in self.available_module:
1822- self.allowed_analysis.append('MadAnalysis5')
1823+ self.allowed_analysis.append('MadAnalysis5')
1824+ if 'Rivet' in self.available_module:
1825+ self.allowed_analysis.append('Rivet')
1826
1827 if self.allowed_analysis:
1828 self.allowed_analysis.append('OFF')
1829@@ -765,8 +782,32 @@
1830 return False
1831 else:
1832 return False
1833-
1834-
1835+
1836+ def consistency_shower_analysis(self, vshower, vanalysis):
1837+ """consistency_XX_YY(val_XX, val_YY)
1838+ -> XX is the new key set by the user to a new value val_XX
1839+ -> YY is another key
1840+ -> return value should be None or "replace_YY"
1841+ """
1842+
1843+ if vshower != 'Pythia8' and vanalysis == 'Rivet':
1844+ return 'OFF' #new value for analysis
1845+
1846+ return None
1847+
1848+ def consistency_analysis_shower(self, vanalysis, vshower):
1849+ """consistency_XX_YY(val_XX, val_YY)
1850+ -> XX is the new key set by the user to a new value val_XX
1851+ -> YY is another key
1852+ -> return value should be None or "replace_YY"
1853+ """
1854+
1855+ if vshower != 'Pythia8' and vanalysis == 'Rivet':
1856+ return 'Pythia8' #new value for analysis
1857+
1858+ return None
1859+
1860+
1861 def set_default_analysis(self):
1862 """initialise the switch for analysis"""
1863
1864@@ -1986,11 +2027,8 @@
1865 return self.list_completion(text, self._run_options + ['-f',
1866 '--tag=','--no_default'], line)
1867
1868- complete_delphes = complete_pgs
1869-
1870-
1871-
1872-
1873+ complete_delphes = complete_pgs
1874+ complete_rivet = complete_pgs
1875
1876 #===============================================================================
1877 # MadEventCmd
1878@@ -2122,6 +2160,10 @@
1879 if not os.path.exists(pjoin(path, 'plot_events')):
1880 logger.info("No valid MadAnalysis path found")
1881 continue
1882+ elif key == "rivet_path":
1883+ if not os.path.exists(pjoin(path, 'bin', 'rivet')):
1884+ logger.info("No valid rivet path found")
1885+ continue
1886 elif key == "td_path":
1887 if not os.path.exists(pjoin(path, 'td')):
1888 logger.info("No valid td path found")
1889@@ -2360,9 +2402,164 @@
1890 args.pop(0)
1891
1892 self.run_generate_events(switch_mode, args)
1893-
1894-
1895-
1896+
1897+ self.postprocessing()
1898+
1899+
1900+ # postprocessing : runs after all the event generation has been done
1901+ # even for the 'scan' mode, madevent->pythia->madevent->pythia->...->POSTPROCESSING
1902+ def postprocessing(self):
1903+
1904+ # Run Rivet postprocessor
1905+ cmd_do_rivet = common_run.CommonRunCmd.do_rivet(self,"--no_default",True)
1906+ if cmd_do_rivet:
1907+ rivet_config = cmd_do_rivet[0]
1908+ postprocess_RIVET = cmd_do_rivet[1]
1909+ postprocess_CONTUR = cmd_do_rivet[2]
1910+ if postprocess_RIVET or postprocess_CONTUR:
1911+ self.rivet_postprocessing(rivet_config, postprocess_RIVET, postprocess_CONTUR)
1912+
1913+ def rivet_postprocessing(self, rivet_config, postprocess_RIVET, postprocess_CONTUR):
1914+
1915+ # Check number of Rivet jobs to run
1916+ run_dirs = [pjoin(self.me_dir, 'Events',run_name)
1917+ for run_name in self.postprocessing_dirs]
1918+
1919+ nb_rivet = len(run_dirs)
1920+
1921+ if postprocess_RIVET:
1922+
1923+ # Submit Rivet jobs
1924+ for i_rivet in range(nb_rivet):
1925+ self.cluster.submit2(pjoin(run_dirs[i_rivet], "run_rivet.sh"), argument=[str(i_rivet)])
1926+
1927+ startRivet = time.time()
1928+
1929+ def wait_monitoring(Idle, Running, Done):
1930+ if Idle+Running+Done == 0:
1931+ return
1932+ logger.info('Rivet analysis jobs: %d Idle, %d Running, %d Done [%s]'\
1933+ %(Idle, Running, Done, misc.format_time(time.time() - startRivet)))
1934+ self.cluster.wait(pjoin(self.me_dir, 'Events'),wait_monitoring)
1935+
1936+ self.update_status("postprocessing rivet done", level="rivet")
1937+
1938+ if postprocess_CONTUR:
1939+
1940+ self.update_status("Starting postprocess contur", level="rivet")
1941+
1942+ set_env = "#!{0}\n".format(misc.which('bash' if misc.get_shell_type() in ['bash',None] else 'tcsh'))
1943+ rivet_path = self.options['rivet_path']
1944+ yoda_path = self.options['yoda_path']
1945+ set_env = set_env + "# RIVET/YODA PATH SETUP\n"
1946+ set_env = set_env + "export PATH={0}:{1}:$PATH\n"\
1947+ .format(pjoin(rivet_path, 'bin'),\
1948+ pjoin(yoda_path, 'bin'))
1949+ set_env = set_env + "export LD_LIBRARY_PATH={0}:{1}:{2}:{3}:$LD_LIBRARY_PATH\n"\
1950+ .format(pjoin(rivet_path, 'lib'),\
1951+ pjoin(rivet_path, 'lib64'),\
1952+ pjoin(yoda_path, 'lib'),\
1953+ pjoin(yoda_path, 'lib64'))
1954+ major, minor = sys.version_info[0:2]
1955+ set_env = set_env + "export PYTHONPATH={0}:{1}:{2}:{3}:$PYTHONPATH\n\n"\
1956+ .format(pjoin(rivet_path, 'lib', 'python%s.%s' %(major,minor), 'site-packages'),\
1957+ pjoin(rivet_path, 'lib64', 'python%s.%s' %(major,minor), 'site-packages'),\
1958+ pjoin(yoda_path, 'lib', 'python%s.%s' %(major,minor), 'site-packages'),\
1959+ pjoin(yoda_path, 'lib64', 'python%s.%s' %(major,minor), 'site-packages'))
1960+
1961+ contur_path = self.options['contur_path']
1962+ set_env = set_env + "# CONTUR PATH SETUP\n"
1963+ set_env = set_env + "export PATH={0}:$PATH\n".format(pjoin(contur_path, 'python%s.%s' %(major,minor), 'bin'))
1964+ set_env = set_env + "export PYTHONPATH={0}:$PYTHONPATH\n".format(pjoin(contur_path, 'python%s.%s' %(major,minor)))
1965+
1966+ set_env = set_env + "source {0} >> contur.log 2>&1\n\n".format(pjoin(contur_path, "contur", "setupContur.sh"))
1967+
1968+ os.system("mkdir -p {0}".format(pjoin(self.me_dir, 'Analysis', 'contur')))
1969+
1970+ if nb_rivet == 1:
1971+ this_yoda_file = pjoin(run_dirs[0], "rivet_result.yoda")
1972+ os.system("ln -s {0} {1}".format(this_yoda_file, pjoin(self.me_dir, 'Analysis', 'contur', 'rivet_result.yoda')))
1973+ if not rivet_config["weight_name"] == "None":
1974+ contur_cmd = 'contur --wn "{0}" {1}\n'.format(rivet_config["weight_name"], pjoin(self.me_dir, 'Analysis', 'contur', 'rivet_result.yoda'))
1975+ else:
1976+ contur_cmd = 'contur {0}\n'.format(pjoin(self.me_dir, 'Analysis', 'contur', 'rivet_result.yoda'))
1977+ else:
1978+ # Link yoda and params files inside analysis/contur/scan directory
1979+ scan_subdirs = []
1980+ for i_rivet in range(nb_rivet):
1981+ this_scan_dir = pjoin(self.me_dir, 'Analysis', 'contur', 'scan', rivet_config["contur_ra"])
1982+ os.system("mkdir -p {0}".format(this_scan_dir))
1983+
1984+ this_scan_subdir = pjoin(this_scan_dir, str(i_rivet+1).zfill(4))
1985+ scan_subdirs.append(this_scan_subdir)
1986+ os.mkdir(this_scan_subdir)
1987+
1988+ this_yoda_file = pjoin(run_dirs[i_rivet], "rivet_result.yoda")
1989+ this_param_file = pjoin(run_dirs[i_rivet], "params.dat")
1990+ os.system("ln -s {0} {1}".format(this_yoda_file, pjoin(this_scan_subdir, "runpoint_"+str(i_rivet+1).zfill(4)+".yoda")))
1991+ os.system("ln -s {0} {1}".format(this_param_file, pjoin(this_scan_subdir, "params.dat")))
1992+
1993+ if rivet_config['xaxis_relvar'] or rivet_config['yaxis_relvar']:
1994+ f_params = open(pjoin(run_dirs[i_rivet], "params.dat"))
1995+ f_relparams = open(pjoin(run_dirs[i_rivet], "params_replace.dat"), "w")
1996+ rivet_config.setRelevantParamCard(f_params=f_params,f_relparams=f_relparams)
1997+ f_params.close()
1998+ f_relparams.close()
1999+
2000+ files.mv(pjoin(run_dirs[i_rivet], "params_replace.dat"), pjoin(run_dirs[i_rivet], "params.dat"))
2001+
2002+ contur_add = ""
2003+ if not (rivet_config["contur_add"] == "default" or rivet_config["contur_add"] == None):
2004+ contur_add = " " + rivet_config["contur_add"]
2005+
2006+ if rivet_config["weight_name"] == "None":
2007+ contur_cmd = 'contur -g scan >> contur.log 2>&1\n'
2008+ else:
2009+ contur_cmd = 'contur -g scan --wn "{0}" >> contur.log 2>&1\n'.format(rivet_config["weight_name"] + contur_add)
2010+
2011+ if rivet_config["draw_contur_heatmap"]:
2012+
2013+ axis_log = ""
2014+ if rivet_config["xaxis_log"]:
2015+ axis_log = axis_log + " --xlog"
2016+ if rivet_config["yaxis_log"]:
2017+ axis_log = axis_log + " --ylog"
2018+
2019+ axis_label = ""
2020+ if rivet_config["xaxis_label"]:
2021+ axis_label = axis_label + " -x " + rivet_config["xaxis_label"]
2022+ if rivet_config["yaxis_label"]:
2023+ axis_label = axis_label + " -y " + rivet_config["yaxis_label"]
2024+
2025+ if rivet_config["xaxis_relvar"]:
2026+ if rivet_config["xaxis_label"]:
2027+ xaxis_var = rivet_config["xaxis_label"]
2028+ else:
2029+ xaxis_var = "xaxis_relvar"
2030+ else:
2031+ xaxis_var = rivet_config["xaxis_var"]
2032+ if rivet_config["yaxis_relvar"]:
2033+ if rivet_config["yaxis_label"]:
2034+ yaxis_var = rivet_config["yaxis_label"]
2035+ else:
2036+ yaxis_var = "yaxis_relvar"
2037+ else:
2038+ yaxis_var = rivet_config["yaxis_var"]
2039+
2040+ contur_cmd = contur_cmd + 'contur-plot ANALYSIS/contur.map {0} {1} {2} {3}' \
2041+ .format(xaxis_var, yaxis_var,axis_label, axis_log)
2042+
2043+ wrapper = open(pjoin(self.me_dir, "Analysis", "contur", "run_contur.sh"), "w")
2044+ wrapper.write(set_env)
2045+
2046+ wrapper.write('{0}\n'.format(contur_cmd))
2047+ wrapper.close()
2048+
2049+ misc.call(["run_contur.sh"], cwd=(pjoin(self.me_dir, "Analysis", "contur")))
2050+
2051+ logger.info("Contur outputs are stored in {0}".format(pjoin(self.me_dir, "Analysis", "contur","conturPlot")))
2052+ self.update_status("postprocessing contur done", level="rivet")
2053+
2054 # this decorator handle the loop related to scan.
2055 @common_run.scanparamcardhandling()
2056 def run_generate_events(self, switch_mode, args):
2057@@ -2471,10 +2668,11 @@
2058 # shower launches pgs/delphes if needed
2059 self.exec_cmd('shower --no_default', postcmd=False, printcmd=False)
2060 self.exec_cmd('madanalysis5_hadron --no_default', postcmd=False, printcmd=False)
2061+ self.exec_cmd('rivet --no_default', postcmd=False, printcmd=False)
2062 self.store_result()
2063
2064 if self.allow_notification_center:
2065- misc.apple_notify('Run %s finished' % os.path.basename(self.me_dir),
2066+ misc.system_notify('Run %s finished' % os.path.basename(self.me_dir),
2067 '%s: %s +- %s ' % (self.results.current['run_name'],
2068 self.results.current['cross'],
2069 self.results.current['error']))
2070@@ -3896,16 +4094,52 @@
2071 tag = self.run_tag
2072
2073 PY8_Card.subruns[0].systemSet('Beams:LHEF',"unweighted_events.lhe.gz")
2074- if PY8_Card['HEPMCoutput:file'] in ['auto', 'autoremove']:
2075- if PY8_Card['HEPMCoutput:file'] == 'autoremove':
2076- self.to_store.append('nopy8')
2077- elif 'nopy8' in self.to_store:
2078- self.to_store.remove('nopy8')
2079- HepMC_event_output = pjoin(self.me_dir,'Events', self.run_name,
2080- '%s_pythia8_events.hepmc'%tag)
2081+
2082+ hepmc_format = PY8_Card['HEPMCoutput:file'].lower()
2083+ if hepmc_format == "auto":
2084+ hepmc_format = "hepmc.gz"
2085+ elif hepmc_format == "autoremove":
2086+ hepmc_format = "hepmcremove"
2087+
2088+ # output format : hepmc/fifo
2089+ if hepmc_format.startswith("hepmc"):
2090+
2091+ hepmc_specs = hepmc_format.split('@')
2092+ hepmc_path = pjoin(self.me_dir,'Events', self.run_name, '%s_pythia8_events.hepmc'%tag)
2093+
2094+ # In case @ is given (output path)
2095+ if len(hepmc_specs) > 1:
2096+ if os.path.isabs(hepmc_specs[1]):
2097+ if os.path.exists(hepmc_specs[1]):
2098+ os.mkdir(pjoin(hepmc_specs[1], self.run_name))
2099+ self.to_store.append("moveHEPMC@" + pjoin(hepmc_specs[1], self.run_name))
2100+ else:
2101+ logger.warning("%s does not exist, using default output path"%hepmc_specs[1])
2102+ else:
2103+ self.to_store.append("moveHEPMC@" + pjoin(self.me_dir, 'Events', hepmc_specs[1], self.run_name))
2104+ os.mkdir(pjoin(self.me_dir, 'Events', hepmc_specs[1], self.run_name))
2105+
2106+ # Compress if .gz is given
2107+ if hepmc_specs[0].endswith(".gz"):
2108+ if not 'compressHEPMC' in self.to_store:
2109+ self.to_store.append('compressHEPMC')
2110+ else:
2111+ if 'compressHEPMC' in self.to_store:
2112+ self.to_store.remove('compressHEPMC')
2113+
2114+ # Remove if remove is given
2115+ if hepmc_specs[0].endswith("remove"):
2116+ if not 'removeHEPMC' in self.to_store:
2117+ self.to_store.append('removeHEPMC')
2118+ else:
2119+ if 'removeHEPMC' in self.to_store:
2120+ self.to_store.remove('removeHEPMC')
2121+
2122+ HepMC_event_output=hepmc_path
2123 PY8_Card.MadGraphSet('HEPMCoutput:file','%s_pythia8_events.hepmc'%tag, force=True)
2124- elif PY8_Card['HEPMCoutput:file'].startswith('fifo'):
2125- fifo_specs = PY8_Card['HEPMCoutput:file'].split('@')
2126+
2127+ elif hepmc_format.startswith('fifo'):
2128+ fifo_specs = hepmc_format.split('@')
2129 fifo_path = None
2130 if len(fifo_specs)<=1:
2131 fifo_path = pjoin(self.me_dir,'Events', self.run_name,'PY8.hepmc.fifo')
2132@@ -3930,13 +4164,11 @@
2133 # Use defaultSet not to overwrite the current userSet status
2134 PY8_Card.defaultSet('HEPMCoutput:file',fifo_path)
2135 HepMC_event_output=fifo_path
2136- elif PY8_Card['HEPMCoutput:file'] in ['','/dev/null','None']:
2137+ elif hepmc_format in ['','/dev/null','None']:
2138 logger.warning('User disabled the HepMC output of Pythia8.')
2139 HepMC_event_output = None
2140 else:
2141- # Normalize the relative path if given as relative by the user.
2142- HepMC_event_output = pjoin(self.me_dir,'Events', self.run_name,
2143- PY8_Card['HEPMCoutput:file'])
2144+ raise InvalidCmd("Unknow HEPMCoutput:file setting, hepmc/hepmc.gz/hepmcremove/fifo")
2145
2146 # We specify by hand all necessary parameters, so that there is no
2147 # need to read parameters from the Banner.
2148@@ -4141,7 +4373,7 @@
2149 args.remove('--no_default')
2150 else:
2151 no_default = False
2152-
2153+
2154 if not self.run_name:
2155 self.check_pythia8(args)
2156 self.configure_directory(html_opening =False)
2157@@ -5277,9 +5509,7 @@
2158
2159 if not self.run_name:
2160 return
2161-
2162-
2163-
2164+
2165 if not self.to_store:
2166 return
2167
2168@@ -5310,13 +5540,23 @@
2169 file_path = pjoin(p, n ,'%s_pythia8_events.hepmc'%t)
2170 self.to_store.remove('pythia8')
2171 if os.path.isfile(file_path):
2172- if 'nopy8' in self.to_store:
2173+ if 'removeHEPMC' in self.to_store:
2174 os.remove(file_path)
2175- else:
2176- self.update_status('Storing Pythia8 files of previous run',
2177- level='pythia', error=True)
2178+
2179+ self.update_status('Storing Pythia8 files of previous run', level='pythia', error=True)
2180+ if 'compressHEPMC' in self.to_store:
2181 misc.gzip(file_path,stdout=file_path)
2182-
2183+ hepmc_fileformat = ".gz"
2184+
2185+ moveHEPMC_in_to_store = None
2186+ for to_store in self.to_store:
2187+ if "moveHEPMC" in to_store:
2188+ moveHEPMC_in_to_store = to_store
2189+
2190+ if not moveHEPMC_in_to_store == None:
2191+ move_hepmc_path = moveHEPMC_in_to_store.split("@")[1]
2192+ os.system("mv " + file_path + hepmc_fileformat + " " + move_hepmc_path)
2193+
2194 self.update_status('Done', level='pythia',makehtml=False,error=True)
2195 self.results.save()
2196
2197@@ -5751,15 +5991,16 @@
2198
2199
2200 # when are we force to change the tag new_run:previous run requiring changes
2201- upgrade_tag = {'parton': ['parton','pythia','pgs','delphes','madanalysis5_hadron','madanalysis5_parton'],
2202+ upgrade_tag = {'parton': ['parton','pythia','pgs','delphes','madanalysis5_hadron','madanalysis5_parton', 'rivet'],
2203 'pythia': ['pythia','pgs','delphes','madanalysis5_hadron'],
2204- 'pythia8': ['pythia8','pgs','delphes','madanalysis5_hadron'],
2205+ 'pythia8': ['pythia8','pgs','delphes','madanalysis5_hadron', 'rivet'],
2206 'pgs': ['pgs'],
2207 'delphes':['delphes'],
2208 'madanalysis5_hadron':['madanalysis5_hadron'],
2209 'madanalysis5_parton':['madanalysis5_parton'],
2210 'plot':[],
2211- 'syscalc':[]}
2212+ 'syscalc':[],
2213+ 'rivet':['rivet']}
2214
2215 if name == self.run_name:
2216 if reload_card:
2217@@ -6149,8 +6390,10 @@
2218 cards.append('madanalysis5_parton_card.dat')
2219 if switch['analysis'].upper() in ['MADANALYSIS5'] and not switch['shower']=='OFF':
2220 cards.append('madanalysis5_hadron_card.dat')
2221- if switch['analysis'].upper() in ['MADANALYSIS4']:
2222+ elif switch['analysis'].upper() in ['MADANALYSIS4']:
2223 cards.append('plot_card.dat')
2224+ elif switch['analysis'].upper() in ['RIVET']:
2225+ cards.append('rivet_card.dat')
2226
2227 self.keep_cards(cards)
2228
2229
2230=== modified file 'madgraph/interface/madgraph_interface.py'
2231--- madgraph/interface/madgraph_interface.py 2022-03-09 13:09:35 +0000
2232+++ madgraph/interface/madgraph_interface.py 2022-05-06 14:56:16 +0000
2233@@ -24,6 +24,7 @@
2234 import cmath
2235 import glob
2236 import logging
2237+import operator
2238 import optparse
2239 import os
2240 import pydoc
2241@@ -1053,6 +1054,8 @@
2242 logger.info("No model currently active, so we import the Standard Model")
2243 self.do_import('model sm')
2244
2245+ argproc_noopt = [a for a in args[1:] if not (a.startswith('--') and "=" in a)]
2246+
2247 if args[-1].startswith('--optimize'):
2248 if args[2] != '>':
2249 raise self.InvalidCmd('optimize mode valid only for 1->N processes. (See model restriction for 2->N)')
2250@@ -1067,9 +1070,9 @@
2251 if not isinstance(self._curr_model, model_reader.ModelReader):
2252 self._curr_model = model_reader.ModelReader(self._curr_model)
2253 self._curr_model.set_parameters_and_couplings(path)
2254- self.check_process_format(' '.join(args[1:-1]))
2255- else:
2256- self.check_process_format(' '.join(args[1:]))
2257+
2258+ self.check_process_format(' '.join(argproc_noopt))
2259+
2260
2261
2262 def check_process_format(self, process):
2263@@ -2902,11 +2905,12 @@
2264 _import_formats = ['model_v4', 'model', 'proc_v4', 'command', 'banner']
2265 _install_opts = ['Delphes', 'MadAnalysis4', 'ExRootAnalysis',
2266 'update', 'Golem95', 'QCDLoop', 'maddm', 'maddump',
2267- 'looptools', 'MadSTR']
2268+ 'looptools', 'MadSTR', 'RunningCoupling']
2269
2270 # The targets below are installed using the HEPToolsInstaller.py script
2271 _advanced_install_opts = ['pythia8','zlib','boost','lhapdf6','lhapdf5','collier',
2272- 'hepmc','mg5amc_py8_interface','ninja','oneloop','MadAnalysis5']
2273+ 'hepmc','mg5amc_py8_interface','ninja','oneloop','MadAnalysis5',
2274+ 'yoda', 'rivet', 'fastjet', 'fjcontrib', 'contur']
2275
2276 _install_opts.extend(_advanced_install_opts)
2277
2278@@ -2945,6 +2949,9 @@
2279 'madanalysis_path': './MadAnalysis',
2280 'madanalysis5_path':'./HEPTools/madanalysis5/madanalysis5',
2281 'pythia-pgs_path':'./pythia-pgs',
2282+ 'rivet_path' : './HEPTools/rivet',
2283+ 'yoda_path' : './HEPTools/yoda',
2284+ 'contur_path' : './HEPTools/contur',
2285 'td_path':'./td',
2286 'delphes_path':'./Delphes',
2287 'exrootanalysis_path':'./ExRootAnalysis',
2288@@ -2958,7 +2965,6 @@
2289 'f2py_compiler_py2':None,
2290 'f2py_compiler_py3':None,
2291 'cpp_compiler':None,
2292- 'auto_update':7,
2293 'cluster_type': 'condor',
2294 'cluster_queue': None,
2295 'cluster_status_update': (600, 30),
2296@@ -2999,6 +3005,7 @@
2297 'max_t_for_channel': 99, # means no restrictions
2298 'zerowidth_tchannel': True,
2299 'nlo_mixed_expansion':True,
2300+ 'auto_update':7,
2301 }
2302
2303 options_madevent = {'automatic_html_opening':True,
2304@@ -3591,13 +3598,7 @@
2305
2306 elif args[0] == 'coupling_order':
2307 hierarchy = list(self._curr_model['order_hierarchy'].items())
2308- #self._curr_model.get_order_hierarchy().items()
2309- def order(first, second):
2310- if first[1] < second[1]:
2311- return -1
2312- else:
2313- return 1
2314- hierarchy.sort(order)
2315+ hierarchy.sort(key=operator.itemgetter(1))
2316 for order in hierarchy:
2317 print(' %s : weight = %s' % order)
2318
2319@@ -6031,15 +6032,16 @@
2320 '--with_pythia8=%s'%self.options['pythia8_path'])
2321
2322 # Special rules for certain tools
2323- if tool=='madanalysis5':
2324+ if tool in ['madanalysis5', 'rivet']:
2325 add_options.append('--mg5_path=%s'%MG5DIR)
2326 if not any(opt.startswith(('--with_fastjet', '--veto_fastjet')) for opt in add_options):
2327 fastjet_config = misc.which(self.options['fastjet'])
2328 if fastjet_config:
2329 add_options.append('--with_fastjet=%s'%fastjet_config)
2330- else:
2331+ elif tool in ['madanalysis5']:
2332 add_options.append('--with_fastjet')
2333-
2334+
2335+ if tool in ['madanalysis5']:
2336 if self.options['delphes_path'] and os.path.isdir(
2337 os.path.normpath(pjoin(MG5DIR,self.options['delphes_path']))):
2338 add_options.append('--with_delphes3=%s'%\
2339@@ -6203,7 +6205,28 @@
2340 After having made sure to have selected a C++ compiler in the 'cpp' option of
2341 MG5aMC that supports quadruple precision (typically g++ based on gcc 4.6+).""")
2342 self.options['ninja'] = pjoin(prefix,'lib')
2343- self.exec_cmd('save options %s ninja' % config_file, printcmd=False, log=False)
2344+ self.exec_cmd('save options %s ninja' % config_file, printcmd=False, log=False)
2345+ elif tool == 'contur':
2346+ to_save = ['contur_path']
2347+ # check that rivet/yoda are correctly linked:
2348+ self.options['%s_path' % tool] = pjoin(prefix, tool)
2349+ if os.path.exists(pjoin(prefix, 'yoda')):
2350+ self.options['yoda_path'] = pjoin(prefix, 'yoda')
2351+ to_save.append('yoda_path')
2352+ if os.path.exists(pjoin(prefix, 'rivet')):
2353+ self.options['rivet_path'] = pjoin(prefix, 'rivet')
2354+ to_save.append('rivet_path')
2355+ self.exec_cmd('save options %s %s' % (config_file,' '.join(to_save)),
2356+ printcmd=False, log=False)
2357+ elif tool == 'rivet':
2358+ to_save = ['rivet_path']
2359+ # check that rivet/yoda are correctly linked:
2360+ self.options['%s_path' % tool] = pjoin(prefix, tool)
2361+ if os.path.exists(pjoin(prefix, 'yoda')):
2362+ self.options['yoda_path'] = pjoin(prefix, 'yoda')
2363+ to_save.append('yoda_path')
2364+ self.exec_cmd('save options %s %s' % (config_file,' '.join(to_save)),
2365+ printcmd=False, log=False)
2366 elif '%s_path' % tool in self.options:
2367 self.options['%s_path' % tool] = pjoin(prefix, tool)
2368 self.exec_cmd('save options %s %s_path' % (config_file,tool), printcmd=False, log=False)
2369@@ -6581,7 +6604,7 @@
2370 # read the __init__.py to check if we need to add a new executable
2371 pyvers=sys.version[0]
2372 try:
2373- __import__('PLUGIN.%s' % name, globals(), locals(), [], -1)
2374+ __import__('PLUGIN.%s' % name, globals(), locals(), [])
2375 plugin = sys.modules['PLUGIN.%s' % name]
2376 new_interface = plugin.new_interface
2377 new_output = plugin.new_output
2378@@ -6589,6 +6612,7 @@
2379 minimal_mg5amcnlo_version = plugin.minimal_mg5amcnlo_version
2380 maximal_mg5amcnlo_version = plugin.maximal_mg5amcnlo_version
2381 except Exception as error:
2382+ print(error)
2383 if six.PY2:
2384 raise Exception('Plugin %s fail to be loaded. Please contact the author of the PLUGIN\n Error %s' % (name, error))
2385 elif six.PY3:
2386@@ -6756,12 +6780,11 @@
2387 opt = options_name[args[0]]
2388 if opt=='golem':
2389 self.options[opt] = pjoin(MG5DIR,name,'lib')
2390- self.exec_cmd('save options %s' % opt, printcmd=False)
2391+ self.exec_cmd('save options %s' % opt, printcmd=False)
2392 elif self.options[opt] != self.options_configuration[opt]:
2393 self.options[opt] = self.options_configuration[opt]
2394 self.exec_cmd('save options %s' % opt, printcmd=False)
2395-
2396-
2397+
2398
2399 def install_update(self, args, wget):
2400 """ check if the current version of mg5 is up-to-date.
2401@@ -7471,6 +7494,10 @@
2402 raise self.RWError('Could not load processes from file %s' % args[1])
2403
2404
2405+ def post_install_RunningCoupling(self):
2406+
2407+ shutil.move('RunningCoupling', pjoin('Template', 'Running'))
2408+
2409 def do_customize_model(self, line):
2410 """create a restriction card in a interactive way"""
2411
2412@@ -7693,9 +7720,8 @@
2413 logger.info("Change EW scheme to %s for the model %s. Note that YOU are responsible of the full validity of the input in that scheme." %\
2414 (self._curr_model.get('name'), args[1]))
2415 else:
2416- logger.info("Change EW scheme to %s for the model %s. Note that SM is assume here.")
2417+ logger.info("Change EW scheme to %s for the model %s. Note that SM is assume here.",self._curr_model.get('name'), args[1])
2418 logger.info("Importing a new model will restore the default scheme")
2419-
2420 self._curr_model.change_electroweak_mode(args[1])
2421 elif args[0] == "complex_mass_scheme":
2422 old = self.options[args[0]]
2423@@ -8032,6 +8058,11 @@
2424 flaglist.append('store_model')
2425 if '--hel_recycling=False' in args:
2426 flaglist.append('no_helrecycling')
2427+
2428+ #forbid helicity recycling for spin 3/2 and spin 2
2429+ if any(spin > 3 for spin in self._curr_model.get_all_spin()):
2430+ flaglist.append('no_helrecycling')
2431+ args.append('--hel_recycling=False')
2432
2433 line_options = dict( (arg[2:].split('=') if "=" in arg else (arg[2:], True))
2434 for arg in args if arg.startswith('--'))
2435
2436=== modified file 'madgraph/interface/reweight_interface.py'
2437--- madgraph/interface/reweight_interface.py 2021-12-03 15:40:10 +0000
2438+++ madgraph/interface/reweight_interface.py 2022-05-06 14:56:16 +0000
2439@@ -94,7 +94,8 @@
2440
2441 self.options = {'curr_dir': os.path.realpath(os.getcwd()),
2442 'rwgt_name':None,
2443- "allow_missing_finalstate":False}
2444+ "allow_missing_finalstate":False,
2445+ "identical_particle_in_prod_and_decay": "average"}
2446
2447 self.events_file = None
2448 self.processes = {}
2449@@ -421,6 +422,10 @@
2450 pass
2451 # this line is meant to be parsed by common_run_interface and change the way this class is called.
2452 #It has no direct impact on this class.
2453+ elif args[0] == "identical_particle_in_prod_and_decay":
2454+ if args[1].lower() not in ['average', 'max', 'crash']:
2455+ raise Exception("option identical_particle_in_prod_and_decay can only be one of the following ['average', 'max', 'crash']")
2456+ self.options[args[0]] = args[1].lower()
2457 else:
2458 logger.critical("unknown option! %s. Discard line." % args[0])
2459
2460@@ -471,7 +476,6 @@
2461 @misc.mute_logger()
2462 def do_launch(self, line):
2463 """end of the configuration launched the code"""
2464-
2465 args = self.split_arg(line)
2466 opts = self.check_launch(args)
2467 if opts['rwgt_name']:
2468@@ -493,8 +497,6 @@
2469 while not os.path.exists(pjoin(self.me_dir,'rw_me','rwgt.pkl')):
2470 time.sleep(10+i)
2471 i+=5
2472- print('wait for pickle')
2473- print("loading from pickle")
2474 if not self.rwgt_dir:
2475 self.rwgt_dir = self.me_dir
2476 self.load_from_pickle(keep_name=True)
2477@@ -508,7 +510,7 @@
2478 if not self.rwgt_dir:
2479 self.rwgt_dir = self.me_dir
2480 self.save_to_pickle()
2481-
2482+
2483 # get the mode of reweighting #LO/NLO/NLO_tree/...
2484 type_rwgt = self.get_weight_names()
2485 # get iterator over param_card and the name associated to the current reweighting.
2486@@ -705,6 +707,7 @@
2487
2488 def handle_param_card(self, model_line, args, type_rwgt):
2489
2490+
2491 if self.rwgt_dir:
2492 path_me =self.rwgt_dir
2493 else:
2494@@ -731,7 +734,7 @@
2495 new_card = self.new_param_card.write()
2496 else:
2497 new_card = open(pjoin(rw_dir, 'Cards', 'param_card.dat')).read()
2498-
2499+
2500 # check for potential scan in the new card
2501 pattern_scan = re.compile(r'''^(decay)?[\s\d]*scan''', re.I+re.M)
2502 param_card_iterator = []
2503@@ -754,7 +757,7 @@
2504 new_card = first_card.write()
2505 self.new_param_card = first_card
2506 #first_card.write(pjoin(rw_dir, 'Cards', 'param_card.dat'))
2507-
2508+
2509 # check if "Auto" is present for a width parameter)
2510 if 'block' not in new_card.lower():
2511 raise Exception(str(new_card))
2512@@ -907,7 +910,36 @@
2513 value = param.value
2514 name = '%s_%s' % (block.upper(), '_'.join([str(i) for i in lhacode]))
2515 module.change_para(name, value)
2516-# misc.sprint("recompute module")
2517+ if param_card[block].scale:
2518+ name = "mdl__%s__scale" % block.upper()
2519+ module.change_para(name, param_card[block].scale)
2520+
2521+ #check for running attribute
2522+ update_running_info = False
2523+ if tag == 2:
2524+ if not self.model:
2525+ update_running_info = True
2526+ elif self.model["running_elements"]:
2527+ update_running_info = True
2528+ elif self.second_model:
2529+ if self.second_model["running_elements"]:
2530+ update_running_info = True
2531+ elif not self.model:
2532+ update_running_info = True
2533+ elif self.model["running_elements"]:
2534+ update_running_info = True
2535+ if update_running_info:
2536+ try:
2537+ run_card = banner.RunCard(self.banner.get('run_card'))
2538+ module.set_fixed_extra_scale(run_card['fixed_extra_scale'])
2539+ module.set_mue_over_ref(run_card['mue_over_ref'])
2540+ module.set_mue_ref_fixed(run_card['mue_ref_fixed'])
2541+ module.set_maxjetflavor(run_card['maxjetflavor'])
2542+ module.set_asmz(param_card.get('sminputs').get((3,)).value)
2543+ module.set_nloop(2)
2544+ except Exception:
2545+ if self.model:
2546+ raise
2547 module.update_all_coup()
2548
2549 return param_card_iterator, tag_name
2550@@ -1244,7 +1276,15 @@
2551
2552 module = self.f2pylib[moduletag]
2553
2554- p = event.get_momenta(orig_order)
2555+ if self.keep_ordering:
2556+ all_p = [event.get_momenta(orig_order)]
2557+ else:
2558+ all_p = event.get_all_momenta(orig_order)
2559+ if len(all_p) >1:
2560+ if self.helicity_reweighting:
2561+ logger.warning("due to ordering ambiguity, we flip off helicity per helicity reweighting.")
2562+ self.helicity_reweighting = False
2563+
2564 # add helicity information
2565
2566 hel_order = event.get_helicity(orig_order)
2567@@ -1269,49 +1309,76 @@
2568 if to_inc[nb_ext]:
2569 pboost += p
2570 new_event.boost(pboost)
2571- p = new_event.get_momenta(orig_order)
2572+ if self.keep_ordering:
2573+ all_p = [new_event.get_momenta(orig_order)]
2574+ else:
2575+ all_p = new_event.get_all_momenta(orig_order)
2576+ if len(all_p) > 1:
2577+ logger.critical("due to ordering ambiguity, the boost used might not be consistent. please ensure that this is not an issue")
2578 elif (hypp_id == 1 and self.boost_event):
2579 if self.boost_event is not True:
2580 import copy
2581 new_event = copy.deepcopy(event)
2582 new_event.boost(self.boost_event)
2583- p = new_event.get_momenta(orig_order)
2584+ if self.keep_ordering:
2585+ all_p = [new_event.get_momenta(orig_order)]
2586+ else:
2587+ all_p = new_event.get_all_momenta(orig_order)
2588 elif (hasattr(event[1], 'status') and event[1].status == -1) or \
2589 (event[1].px == event[1].py == 0.):
2590+ p = all_p[0]
2591 pboost = lhe_parser.FourMomentum(p[0]) + lhe_parser.FourMomentum(p[1])
2592- for i,thisp in enumerate(p):
2593- p[i] = lhe_parser.FourMomentum(thisp).zboost(pboost).get_tuple()
2594- assert p[0][1] == p[0][2] == 0 == p[1][2] == p[1][2] == 0
2595-
2596- pold = list(p)
2597- p = self.invert_momenta(p)
2598- pdg = list(orig_order[0])+list(orig_order[1])
2599- try:
2600- pid = event.ievent
2601- except AttributeError:
2602- pid = -1
2603- if not self.use_eventid:
2604- pid = -1
2605-
2606- if not scale2:
2607- if hasattr(event, 'scale'):
2608- scale2 = event.scale**2
2609- else:
2610- scale2 = 0
2611-
2612- with misc.chdir(Pdir):
2613- with misc.stdchannel_redirected(sys.stdout, os.devnull):
2614- me_value = module.smatrixhel(pdg, pid, p, event.aqcd, scale2, nhel)
2615-
2616- # for loop we have also the stability status code
2617- if isinstance(me_value, tuple):
2618- me_value, code = me_value
2619- #if code points unstability -> returns 0
2620- hundred_value = (code % 1000) //100
2621- if hundred_value in [4]:
2622- me_value = 0.
2623+ for p in all_p:
2624+ for i,thisp in enumerate(p):
2625+ p[i] = lhe_parser.FourMomentum(thisp).zboost(pboost).get_tuple()
2626+ assert p[0][1] == p[0][2] == 0 == p[1][2] == p[1][2] == 0
2627+
2628+
2629+ if self.options['identical_particle_in_prod_and_decay'] == 'crash':
2630+ if len(all_p) > 1:
2631+ raise Exception("Ambiguous particle in production and decay. crash as requested by \'identical_particle_in_prod_and_decay\'")
2632+
2633+ me_value = 0
2634+ for p in all_p:
2635+ pold = list(p)
2636+ p = self.invert_momenta(p)
2637+ pdg = list(orig_order[0])+list(orig_order[1])
2638+ try:
2639+ pid = event.ievent
2640+ except AttributeError:
2641+ pid = -1
2642+ if not self.use_eventid:
2643+ pid = -1
2644
2645- return me_value
2646+ if not scale2:
2647+ if hasattr(event, 'scale'):
2648+ scale2 = event.scale**2
2649+ else:
2650+ scale2 = 0
2651+
2652+ with misc.chdir(Pdir):
2653+ with misc.stdchannel_redirected(sys.stdout, os.devnull):
2654+ new_value = module.smatrixhel(pdg, pid, p, event.aqcd, scale2, nhel)
2655+
2656+ # for loop we have also the stability status code
2657+ if isinstance(new_value, tuple):
2658+ new_value, code = new_value
2659+ #if code points unstability -> returns 0
2660+ hundred_value = (code % 1000) //100
2661+ if hundred_value in [4]:
2662+ new_value = 0.
2663+ if self.options["identical_particle_in_prod_and_decay"] == "average":
2664+ me_value += new_value
2665+ elif self.options["identical_particle_in_prod_and_decay"] == "max":
2666+ if abs(new_value) > abs(me_value):
2667+ me_value = new_value
2668+ else:
2669+ raise Exception("not valid option")
2670+
2671+ if self.options["identical_particle_in_prod_and_decay"] == "average":
2672+ return me_value / len(all_p)
2673+ else:
2674+ return me_value
2675
2676 def terminate_fortran_executables(self, new_card_only=False):
2677 """routine to terminate all fortran executables"""
2678@@ -1693,28 +1760,15 @@
2679 else:
2680 has_nlo = self.create_standalone_tree_directory(data, second)
2681
2682-
2683+ if has_nlo and not self.rwgt_mode:
2684+ self.rwgt_mode = ['NLO']
2685+
2686 # 5. create the virtual for NLO reweighting ---------------------------
2687 if second and 'virtual_path' in self.dedicated_path:
2688 files.ln(self.dedicated_path['virtual_path'], path_me, name=data['paths'][1])
2689 elif has_nlo and 'NLO' in self.rwgt_mode:
2690 self.create_standalone_virt_directory(data, second)
2691
2692- if False:#not second:
2693- #compile the module to combine the weight
2694- misc.compile(cwd=pjoin(path_me, data['paths'][1], 'Source'))
2695- #link it
2696- if path_me not in sys.path:
2697- sys.path.insert(0, os.path.realpath(path_me))
2698- with misc.chdir(pjoin(path_me)):
2699- mymod = __import__('%s.Source.rwgt2py' % data['paths'][1], globals(), locals(), [])
2700- mymod = mymod.Source.rwgt2py
2701- with misc.stdchannel_redirected(sys.stdout, os.devnull):
2702- mymod.initialise([self.banner.run_card['lpp1'],
2703- self.banner.run_card['lpp2']],
2704- self.banner.run_card.get_lhapdf_id())
2705- self.combine_wgt = mymod.get_wgt
2706-
2707 if self.multicore == 'create':
2708 print("compile OLP", data['paths'][1])
2709 try:
2710@@ -1747,21 +1801,6 @@
2711 common_run_interface.CommonRunCmd.install_lhapdf_pdfset_static(\
2712 mgcmd.options['lhapdf'], None, self.banner.run_card.get_lhapdf_id())
2713
2714- #compile the module to combine the weight
2715- if False:
2716- #use python module instead
2717- misc.compile(cwd=pjoin(path_me, data['paths'][1], 'Source'))
2718- #link it
2719- with misc.chdir(pjoin(path_me)):
2720- if path_me not in sys.path:
2721- sys.path.insert(0, path_me)
2722- mymod = __import__('%s.Source.rwgt2py' % data['paths'][1], globals(), locals(), [],-1)
2723- mymod = mymod.Source.rwgt2py
2724- with misc.stdchannel_redirected(sys.stdout, os.devnull):
2725- mymod.initialise([self.banner.run_card['lpp1'],
2726- self.banner.run_card['lpp2']],
2727- self.banner.run_card.get_lhapdf_id())
2728- self.combine_wgt = mymod.get_wgt
2729
2730
2731 # 6. If we need a new model/process-------------------------------------
2732@@ -1963,6 +2002,7 @@
2733 to_save['rwgt_mode'] = self.rwgt_mode
2734 to_save['rwgt_name'] = self.options['rwgt_name']
2735 to_save['allow_missing_finalstate'] = self.options['allow_missing_finalstate']
2736+ to_save['identical_particle_in_prod_and_decay'] = self.options['identical_particle_in_prod_and_decay']
2737 to_save['nb_library'] = self.nb_library
2738
2739 name = pjoin(self.rwgt_dir, 'rw_me', 'rwgt.pkl')
2740@@ -1985,7 +2025,9 @@
2741 if keep_name:
2742 self.options['rwgt_name'] = obj['rwgt_name']
2743
2744+
2745 self.options['allow_missing_finalstate'] = obj['allow_missing_finalstate']
2746+ self.options['identical_particle_in_prod_and_decay'] = obj['identical_particle_in_prod_and_decay']
2747 old_rwgt = obj['rwgt_dir']
2748
2749 # path to fortran executable
2750
2751=== modified file 'madgraph/iolibs/export_fks.py'
2752--- madgraph/iolibs/export_fks.py 2022-02-15 10:26:00 +0000
2753+++ madgraph/iolibs/export_fks.py 2022-05-06 14:56:16 +0000
2754@@ -97,7 +97,7 @@
2755 #===============================================================================
2756 # copy the Template in a new directory.
2757 #===============================================================================
2758- def copy_fkstemplate(self):
2759+ def copy_fkstemplate(self, model):
2760 """create the directory run_name as a copy of the MadEvent
2761 Template, and clean the directory
2762 For now it is just the same as copy_v4template, but it will be modified
2763@@ -239,6 +239,15 @@
2764 # We need to create the correct open_data for the pdf
2765 self.write_pdf_opendata()
2766
2767+ if model["running_elements"]:
2768+ if not os.path.exists(pjoin(MG5DIR, 'Template',"Running")):
2769+ raise Exception("Library for the running have not been installed. To install them please run \"install RunningCoupling\"")
2770+
2771+ misc.copytree(pjoin(MG5DIR, 'Template',"Running"),
2772+ pjoin(self.dir_path,'Source','RUNNING'))
2773+
2774+
2775+
2776 # I put it here not in optimized one, because I want to use the same makefile_loop.inc
2777 # Also, we overload this function (i.e. it is already defined in
2778 # LoopProcessExporterFortranSA) because the path of the template makefile
2779@@ -1282,12 +1291,25 @@
2780 pass
2781
2782 amp_split_size=len(amp_split_orders)
2783-
2784 text = '! The orders to be integrated for the Born and at NLO\n'
2785 text += 'integer nsplitorders\n'
2786 text += 'parameter (nsplitorders=%d)\n' % len(split_orders)
2787- text += 'character*3 ordernames(nsplitorders)\n'
2788- text += 'data ordernames / %s /\n' % ', '.join(['"%3s"' % o for o in split_orders])
2789+ text += 'character*%d ordernames(nsplitorders)\n' % max([len(o) for o in split_orders])
2790+ step = 5
2791+ if len(split_orders) < step:
2792+ text += 'data ordernames / %s /\n' % ', '.join(['"%3s"' % o for o in split_orders])
2793+ else:
2794+ # this file is linked from f77 and f90 so need to be smart about line splitting
2795+ text += "INTEGER ORDERNAMEINDEX\n"
2796+ for i in range(1,len(split_orders),step):
2797+ start = i
2798+ stop = i+step -1
2799+ data = ', '.join(['"%3s"' % o for o in split_orders[start-1: stop]])
2800+ if stop > len(split_orders):
2801+ stop = len(split_orders)
2802+ text += 'data (ordernames(ORDERNAMEINDEX), ORDERNAMEINDEX=%s,%s) / %s /\n' % (start, stop, data)
2803+
2804+
2805 text += 'integer born_orders(nsplitorders), nlo_orders(nsplitorders)\n'
2806 text += '! the order of the coupling orders is %s\n' % ', '.join(split_orders)
2807 text += 'data born_orders / %s /\n' % ', '.join([str(max_born_orders[o]) for o in split_orders])
2808@@ -1306,7 +1328,7 @@
2809 text += 'double precision amp_split(amp_split_size)\n'
2810 text += 'double complex amp_split_cnt(amp_split_size,2,nsplitorders)\n'
2811 text += 'common /to_amp_split/amp_split, amp_split_cnt\n'
2812-
2813+ writer.line_length=132
2814 writer.writelines(text)
2815
2816 return amp_split_orders, amp_split_size, amp_split_size_born
2817@@ -3985,7 +4007,7 @@
2818 #===============================================================================
2819 # copy the Template in a new directory.
2820 #===============================================================================
2821- def copy_fkstemplate(self):
2822+ def copy_fkstemplate(self, model):
2823 """create the directory run_name as a copy of the MadEvent
2824 Template, and clean the directory
2825 For now it is just the same as copy_v4template, but it will be modified
2826@@ -4172,6 +4194,10 @@
2827 self.write_pdf_opendata()
2828
2829
2830+ if model["running_elements"]:
2831+ shutil.copytree(pjoin(MG5DIR, 'Template',"Running"),
2832+ pjoin(self.dir_path,'Source','RUNNING'))
2833+
2834 # Return to original PWD
2835 os.chdir(cwd)
2836
2837
2838=== modified file 'madgraph/iolibs/export_v4.py'
2839--- madgraph/iolibs/export_v4.py 2022-03-01 09:45:24 +0000
2840+++ madgraph/iolibs/export_v4.py 2022-05-06 14:56:16 +0000
2841@@ -16,10 +16,12 @@
2842 from madgraph.iolibs.helas_call_writers import HelasCallWriter
2843 from six.moves import range
2844 from six.moves import zip
2845-from fractions import Fraction
2846+import six
2847+from madgraph.core import base_objects
2848 """Methods and classes to export matrix elements to v4 format."""
2849
2850 import copy
2851+import math, cmath
2852 from six import StringIO
2853 import itertools
2854 import fractions
2855@@ -709,7 +711,12 @@
2856 replace_dict= {'libraries': set_of_lib,
2857 'model':model_line,
2858 'additional_dsample': '',
2859- 'additional_dependencies':''}
2860+ 'additional_dependencies':'',
2861+ 'running': ''}
2862+
2863+ if self.opt['running']:
2864+ replace_dict['running'] =" $(LIBDIR)librunning.$(libext): RUNNING\n\tcd RUNNING; make"
2865+ replace_dict['libraries'] += " $(LIBDIR)librunning.$(libext) "
2866
2867 if writer:
2868 text = open(path).read() % replace_dict
2869@@ -1301,8 +1308,11 @@
2870 # Mutliply by -1 for those which have an imaginary coefficient.
2871 ampnumbers_list=[coefficient[1]*(-1 if coefficient[0][2] else 1) \
2872 for coefficient in coeff_list]
2873- # Find the common denominator.
2874- commondenom=abs(reduce(fractions.gcd, coefs_list).denominator)
2875+ # Find the common denominator.
2876+ if six.PY2:
2877+ commondenom=abs(reduce(fractions.gcd, coefs_list).denominator)
2878+ else:
2879+ commondenom=abs(reduce(math.gcd, coefs_list).denominator)
2880 num_list=[(coefficient*commondenom).numerator \
2881 for coefficient in coefs_list]
2882 res_list.append("DATA NCONTRIBAMPS%s(%i)/%i/"%(tag_letter,\
2883@@ -1509,7 +1519,7 @@
2884
2885 #misc.sprint("number of iteration", self.myjamp_count)
2886 def format(frac):
2887- if isinstance(frac, Fraction):
2888+ if isinstance(frac, fractions.Fraction):
2889 if frac.denominator == 1:
2890 return str(frac.numerator)
2891 else:
2892@@ -2172,6 +2182,7 @@
2893 """Additional actions needed for setup of Template
2894 """
2895
2896+ self.model = model
2897 #First copy the full template tree if dir_path doesn't exit
2898 if os.path.isdir(self.dir_path):
2899 return
2900@@ -2205,6 +2216,20 @@
2901 # Add file in SubProcesses
2902 shutil.copy(pjoin(self.mgme_dir, 'madgraph', 'iolibs', 'template_files', 'makefile_sa_f_sp'),
2903 pjoin(self.dir_path, 'SubProcesses', 'makefileP'))
2904+
2905+ if model['running_elements']:
2906+ fsock = open( pjoin(self.mgme_dir, 'madgraph', 'iolibs', 'template_files', 'makefile_sa_f_sp'), 'r')
2907+ text = fsock.read()
2908+ fsock.close()
2909+ fsock = open(pjoin(self.dir_path, 'SubProcesses', 'makefileP'),'w')
2910+ text = text.replace('LINKLIBS = -L../../lib/', 'LINKLIBS = -L../../lib/ -lrunning')
2911+ text = text.replace('LIBS =', 'LIBS = $(LIBDIR)/librunning.$(libext)')
2912+ fsock.write(text)
2913+ fsock.close()
2914+ else:
2915+ # Add file in SubProcesses
2916+ shutil.copy(pjoin(self.mgme_dir, 'madgraph', 'iolibs', 'template_files', 'makefile_sa_f_sp'),
2917+ pjoin(self.dir_path, 'SubProcesses', 'makefileP'))
2918
2919 if self.format == 'standalone':
2920 shutil.copy(pjoin(self.mgme_dir, 'madgraph', 'iolibs', 'template_files', 'check_sa.f'),
2921@@ -2215,7 +2240,7 @@
2922 pjoin(self.dir_path, 'Source'))
2923 # add the makefile
2924 filename = pjoin(self.dir_path,'Source','makefile')
2925- self.write_source_makefile(writers.FileWriter(filename))
2926+ self.write_source_makefile(writers.FileWriter(filename),model)
2927
2928 #===========================================================================
2929 # export model files
2930@@ -2265,10 +2290,12 @@
2931 """
2932
2933 source_dir = pjoin(self.dir_path, "Source")
2934- logger.info("Running make for Helas")
2935- misc.compile(arg=['../lib/libdhelas.a'], cwd=source_dir, mode='fortran')
2936- logger.info("Running make for Model")
2937- misc.compile(arg=['../lib/libmodel.a'], cwd=source_dir, mode='fortran')
2938+ logger.info("Running make for Source directory")
2939+ try:
2940+ misc.compile(cwd=source_dir, mode='fortran')
2941+ except:
2942+ misc.compile(arg=['../lib/libdhelas.a'], cwd=source_dir, mode='fortran')
2943+ misc.compile(arg=['../lib/libmodel.a'], cwd=source_dir, mode='fortran')
2944
2945 #===========================================================================
2946 # Create proc_card_mg5.dat for Standalone directory
2947@@ -2306,7 +2333,7 @@
2948
2949 if self.prefix_info:
2950 self.write_f2py_splitter()
2951- self.write_f2py_makefile()
2952+ self.write_f2py_makefile(self.model)
2953 self.write_f2py_check_sa(matrix_elements,
2954 pjoin(self.dir_path,'SubProcesses','check_sa.py'))
2955 else:
2956@@ -2345,10 +2372,14 @@
2957 double precision ANS, ALPHAS, PI,SCALE2
2958 include 'coupl.inc'
2959
2960- PI = 3.141592653589793D0
2961- G = 2* DSQRT(ALPHAS*PI)
2962- CALL UPDATE_AS_PARAM()
2963-c if (scale2.ne.0d0) stop 1
2964+
2965+ if (scale2.eq.0)then
2966+ PI = 3.141592653589793D0
2967+ G = 2* DSQRT(ALPHAS*PI)
2968+ CALL UPDATE_AS_PARAM()
2969+ else
2970+ CALL UPDATE_AS_PARAM2(scale2, ALPHAS)
2971+ endif
2972
2973 %(smatrixhel)s
2974
2975@@ -2418,7 +2449,95 @@
2976 RETURN
2977 END
2978
2979-
2980+
2981+
2982+ subroutine set_fixed_extra_scale(new_value)
2983+ implicit none
2984+CF2PY logical, intent(in) :: new_value
2985+ logical new_value
2986+ logical fixed_extra_scale
2987+ integer maxjetflavor
2988+ double precision mue_over_ref
2989+ double precision mue_ref_fixed
2990+ common/model_setup_running/maxjetflavor,fixed_extra_scale,mue_over_ref,mue_ref_fixed
2991+
2992+ fixed_extra_scale = new_value
2993+ return
2994+ end
2995+
2996+ subroutine set_mue_over_ref(new_value)
2997+ implicit none
2998+CF2PY double precision, intent(in) :: new_value
2999+ double precision new_value
3000+ logical fixed_extra_scale
3001+ integer maxjetflavor
3002+ double precision mue_over_ref
3003+ double precision mue_ref_fixed
3004+ common/model_setup_running/maxjetflavor,fixed_extra_scale,mue_over_ref,mue_ref_fixed
3005+
3006+ mue_over_ref = new_value
3007+
3008+ return
3009+ end
3010+
3011+ subroutine set_mue_ref_fixed(new_value)
3012+ implicit none
3013+CF2PY double precision, intent(in) :: new_value
3014+ double precision new_value
3015+ logical fixed_extra_scale
3016+ integer maxjetflavor
3017+ double precision mue_over_ref
3018+ double precision mue_ref_fixed
3019+ common/model_setup_running/maxjetflavor,fixed_extra_scale,mue_over_ref,mue_ref_fixed
3020+
3021+ mue_ref_fixed = new_value
3022+
3023+ return
3024+ end
3025+
3026+
3027+ subroutine set_maxjetflavor(new_value)
3028+ implicit none
3029+CF2PY integer, intent(in) :: new_value
3030+ integer new_value
3031+ logical fixed_extra_scale
3032+ integer maxjetflavor
3033+ double precision mue_over_ref
3034+ double precision mue_ref_fixed
3035+ common/model_setup_running/maxjetflavor,fixed_extra_scale,mue_over_ref,mue_ref_fixed
3036+
3037+ maxjetflavor = new_value
3038+
3039+ return
3040+ end
3041+
3042+
3043+ subroutine set_asmz(new_value)
3044+ implicit none
3045+CF2PY double precision, intent(in) :: new_value
3046+ double precision new_value
3047+ integer nloop
3048+ double precision asmz
3049+ common/a_block/asmz,nloop
3050+ asmz = new_value
3051+ write(*,*) "asmz is set to ", new_value
3052+
3053+ return
3054+ end
3055+
3056+ subroutine set_nloop(new_value)
3057+ implicit none
3058+CF2PY integer, intent(in) :: new_value
3059+ integer new_value
3060+ integer nloop
3061+ double precision asmz
3062+ common/a_block/asmz,nloop
3063+ nloop = new_value
3064+ write(*,*) "nloop is set to ", new_value
3065+
3066+ return
3067+ end
3068+
3069 """
3070
3071 allids = list(self.prefix_info.keys())
3072@@ -2500,22 +2619,41 @@
3073 lha = '_'.join([str(i) for i in p.lhacode])
3074 params['%s_%s' % (block.upper(), lha)] = name
3075
3076+ if model['running_elements']:
3077+ add_scale = set()
3078+ for runs in self.model.get('running_elements'):
3079+ for line_run in runs.run_objects:
3080+ for one_element in line_run:
3081+ add_scale.add(one_element.lhablock)
3082+ for block in add_scale:
3083+ if block.upper() == "SMINPUTS":
3084+ continue
3085+ name = block
3086+ params['%s__scale' % (block.upper())] = 'mdl__%s__scale' % (block.upper())
3087+ params['mdl__%s__scale' % (block.upper())] = 'mdl__%s__scale' % (block.upper())
3088+
3089 return params
3090
3091
3092
3093-
3094-
3095 def write_f2py_check_sa(self, matrix_element, writer):
3096 """ Write the general check_sa.py in SubProcesses that calls all processes successively."""
3097 # To be implemented. It is just an example file, i.e. not crucial.
3098 return
3099
3100- def write_f2py_makefile(self):
3101+ def write_f2py_makefile(self, model):
3102 """ """
3103+ template = pjoin(self.mgme_dir, 'madgraph', 'iolibs', 'template_files', 'makefile_sa_f2py')
3104+ destination = pjoin(self.dir_path, 'SubProcesses', 'makefile')
3105+
3106 # Add file in SubProcesses
3107- shutil.copy(pjoin(self.mgme_dir, 'madgraph', 'iolibs', 'template_files', 'makefile_sa_f2py'),
3108- pjoin(self.dir_path, 'SubProcesses', 'makefile'))
3109+ if model['running_elements']:
3110+ text = open(template,'r').read()
3111+ text = text.replace('LINKLIBS_ME = -L../lib/', 'LINKLIBS_ME = -L../lib/ -lrunning ')
3112+ text = text.replace('LINKLIBS_ALL = -L../lib/', 'LINKLIBS_ALL = -L../lib/ -lrunning ')
3113+ open(destination, 'w').write(text)
3114+ else:
3115+ shutil.copy(template, destination)
3116
3117 def create_MA5_cards(self,*args,**opts):
3118 """ Overload the function of the mother so as to bypass this in StandAlone."""
3119@@ -2674,17 +2812,24 @@
3120 #===========================================================================
3121 # write_source_makefile
3122 #===========================================================================
3123- def write_source_makefile(self, writer):
3124+ def write_source_makefile(self, writer, model):
3125 """Write the nexternal.inc file for MG4"""
3126
3127 path = pjoin(_file_path,'iolibs','template_files','madevent_makefile_source')
3128 set_of_lib = '$(LIBDIR)libdhelas.$(libext) $(LIBDIR)libmodel.$(libext)'
3129 model_line='''$(LIBDIR)libmodel.$(libext): MODEL\n\t cd MODEL; make\n'''
3130
3131+ if model['running_elements']:
3132+ running_line = '''$(LIBDIR)librunning.$(libext): RUNNING\n\t cd RUNNING; make\n'''
3133+ set_of_lib += ' $(LIBDIR)librunning.$(libext) '
3134+ else:
3135+ running_line = ''
3136+
3137 replace_dict= {'libraries': set_of_lib,
3138 'model':model_line,
3139 'additional_dsample': '',
3140- 'additional_dependencies':''}
3141+ 'additional_dependencies':'',
3142+ 'running': running_line}
3143
3144 text = open(path).read() % replace_dict
3145
3146@@ -3862,6 +4007,12 @@
3147 # Copy the different python file in the Template
3148 self.copy_python_file()
3149
3150+ if model["running_elements"]:
3151+ if not os.path.exists(pjoin(MG5DIR, 'Template',"Running")):
3152+ raise Exception("Library for the running have not been installed. To install them please run \"install RunningCoupling\"")
3153+ misc.copytree(pjoin(MG5DIR, 'Template',"Running"),
3154+ pjoin(self.dir_path,'Source','RUNNING'))
3155+
3156
3157
3158
3159@@ -4025,7 +4176,7 @@
3160
3161
3162 # Create the matrix.f file, auto_dsig.f file and all inc files
3163- if self.opt['hel_recycling']:
3164+ if 'hel_recycling' in self.opt and self.opt['hel_recycling']:
3165 filename = pjoin(Ppath, 'matrix_orig.f')
3166 else:
3167 filename = pjoin(Ppath, 'matrix.f')
3168@@ -6315,8 +6466,32 @@
3169 self.params_indep = [] # (name, expression, type)
3170 self.params_ext = [] # external parameter
3171 self.p_to_f = parsers.UFOExpressionParserFortran(self.model)
3172- self.mp_p_to_f = parsers.UFOExpressionParserMPFortran(self.model)
3173-
3174+ self.mp_p_to_f = parsers.UFOExpressionParserMPFortran(self.model)
3175+ self.scales = []
3176+ self.MUE = None # extra parameter loop #2 which is running
3177+
3178+ if self.model.get('running_elements'):
3179+ all_elements = set()
3180+ add_scale = set()
3181+ for runs in self.model.get('running_elements'):
3182+ for line_run in runs.run_objects:
3183+ for one_element in line_run:
3184+ all_elements.add(one_element.name)
3185+ add_scale.add(one_element.lhablock)
3186+ all_elements.union(set(self.PS_dependent_key))
3187+ self.PS_dependent_key = list(all_elements)
3188+ MUE = [p for p in self.model.get('parameters')[('external',)] if p.lhablock.lower() == 'loop' and tuple(p.lhacode) == (2,)]
3189+
3190+ if MUE:
3191+ self.MUE = MUE[0]
3192+ self.PS_dependent_key.append(MUE[0].name)
3193+
3194+ try:
3195+ add_scale.remove('SMINPUTS')
3196+ except Exception:
3197+ pass
3198+ self.scales = add_scale
3199+
3200
3201 def pass_parameter_to_case_insensitive(self):
3202 """modify the parameter if some of them are identical up to the case"""
3203@@ -6388,9 +6563,10 @@
3204 def refactorize(self, wanted_couplings = []):
3205 """modify the couplings to fit with MG4 convention """
3206
3207- # Keep only separation in alphaS
3208+ # Keep only separation in alphaS + running one
3209 keys = list(self.model['parameters'].keys())
3210 keys.sort(key=len)
3211+
3212 for key in keys:
3213 to_add = [o for o in self.model['parameters'][key] if o.name]
3214
3215@@ -6400,19 +6576,25 @@
3216 self.params_dep += to_add
3217 else:
3218 self.params_indep += to_add
3219- # same for couplings
3220+
3221+ # same for couplings + tracking which running happens
3222 keys = list(self.model['couplings'].keys())
3223 keys.sort(key=len)
3224+ used_running_key = set()
3225 for key, coup_list in self.model['couplings'].items():
3226 if any([(k in key) for k in self.PS_dependent_key]):
3227- self.coups_dep += [c for c in coup_list if
3228+ to_add = [c for c in coup_list if
3229 (not wanted_couplings or c.name in \
3230 wanted_couplings)]
3231+ if to_add:
3232+ self.coups_dep += to_add
3233+ used_running_key.update(set(key))
3234 else:
3235 self.coups_indep += [c for c in coup_list if
3236 (not wanted_couplings or c.name in \
3237 wanted_couplings)]
3238-
3239+ #store the running parameter that are used
3240+ self.used_running_key = used_running_key
3241 # MG4 use G and not aS as it basic object for alphas related computation
3242 #Pass G in the independant list
3243 if 'G' in self.params_dep:
3244@@ -6421,12 +6603,13 @@
3245 # G.expr = '2*cmath.sqrt(as*pi)'
3246 # self.params_indep.insert(0, self.params_dep.pop(index))
3247 # No need to add it if not defined
3248-
3249- if 'aS' not in self.params_ext:
3250+
3251+ if 'aS' not in self.params_ext and 'aS' not in self.params_indep:
3252 logger.critical('aS not define as external parameter adding it!')
3253 #self.model['parameters']['aS'] = base_objects.ParamCardVariable('aS', 0.138,'DUMMY',(1,))
3254 self.params_indep.append( base_objects. ModelVariable('aS', '0.138','real'))
3255 self.params_indep.append( base_objects. ModelVariable('G', '4.1643','real'))
3256+
3257 def build(self, wanted_couplings = [], full=True):
3258 """modify the couplings to fit with MG4 convention and creates all the
3259 different files"""
3260@@ -6567,11 +6750,29 @@
3261 'madweight','matchbox','madloop_matchbox', 'plugin']:
3262 cp( MG5DIR + '/models/template_files/fortran/makefile_standalone',
3263 self.dir_path + '/makefile')
3264- #elif self.opt['export_format'] in []:
3265- #pass
3266 else:
3267 raise MadGraph5Error('Unknown format')
3268
3269+ if self.opt['export_format'].startswith('standalone'):
3270+ cp( MG5DIR + '/Template/LO/Source/alfas_functions.f',
3271+ self.dir_path)
3272+ cp( MG5DIR + '/Template/LO/Source/alfas.inc',
3273+ self.dir_path)
3274+
3275+ fsock = open(pjoin(self.dir_path, '..', 'cuts.inc'),'w')
3276+ fsock.write('''
3277+ logical fixed_extra_scale
3278+ integer maxjetflavor
3279+ double precision mue_over_ref
3280+ double precision mue_ref_fixed
3281+ common/model_setup_running/maxjetflavor,fixed_extra_scale,mue_over_ref,mue_ref_fixed
3282+ ''')
3283+
3284+ if self.model['running_elements']:
3285+ cp( MG5DIR + '/Template/Running', pjoin(self.dir_path, '..', 'RUNNING'))
3286+
3287+
3288+
3289 def create_coupl_inc(self):
3290 """ write coupling.inc """
3291
3292@@ -6741,18 +6942,20 @@
3293 real_parameters += [param.name for param in self.params_ext
3294 if param.type == 'real'and
3295 is_valid(param.name)]
3296-
3297+
3298 # check the parameter is a CT parameter or not
3299 # if yes, just use the needed ones
3300 real_parameters = [param for param in real_parameters \
3301 if self.check_needed_param(param)]
3302
3303+ real_parameters += ['mdl__%s__scale' % s for s in self.scales]
3304+
3305 fsock.writelines('double precision '+','.join(real_parameters)+'\n')
3306 fsock.writelines('common/params_R/ '+','.join(real_parameters)+'\n\n')
3307 if self.opt['mp']:
3308 mp_fsock.writelines(self.mp_real_format+' '+','.join([\
3309 self.mp_prefix+p for p in real_parameters])+'\n')
3310- mp_fsock.writelines('common/MP_params_R/ '+','.join([\
3311+ mp_fsock.writelines('common/MP_T_params_R/ '+','.join([\
3312 self.mp_prefix+p for p in real_parameters])+'\n\n')
3313
3314 complex_parameters = [param.name for param in self.params_dep +
3315@@ -6996,11 +7199,11 @@
3316 %(mp_prefix)sgal(2) = 1e0_16
3317 """%{'mp_prefix':self.mp_prefix})
3318
3319-
3320+ nb_def_by_file = 50
3321 def create_couplings(self):
3322 """ create couplings.f and all couplingsX.f """
3323
3324- nb_def_by_file = 25
3325+ nb_def_by_file = self.nb_def_by_file
3326
3327 self.create_couplings_main(nb_def_by_file)
3328 nb_coup_indep = 1 + len(self.coups_indep) // nb_def_by_file
3329@@ -7075,19 +7278,73 @@
3330
3331 implicit none
3332 double precision PI, ZERO
3333- logical READLHA
3334+ logical READLHA, FIRST
3335+ data first /.true./
3336+ save first
3337 parameter (PI=3.141592653589793d0)
3338 parameter (ZERO=0d0)
3339 logical updateloop
3340 common /to_updateloop/updateloop
3341- include \'model_functions.inc\'""")
3342+ include \'model_functions.inc\'
3343+ double precision Gother
3344+
3345+ double precision model_scale
3346+ common /model_scale/model_scale
3347+ """)
3348+
3349+ if self.opt['export_format'] in ['madevent', 'madloop_optimized']:
3350+ fsock.writelines("""
3351+ include \'../maxparticles.inc\'
3352+ include \'../cuts.inc\'
3353+ include \'../run.inc\'""")
3354+ else:
3355+ fsock.writelines("""
3356+ include \'../cuts.inc\'
3357+ data maxjetflavor,fixed_extra_scale,mue_over_ref,mue_ref_fixed /5,.false.,1d0,91.188/
3358+ include \'../run.inc\'""")
3359+ fsock.writelines("""
3360+ double precision alphas
3361+ external alphas
3362+ """)
3363 fsock.writelines("""include \'input.inc\'
3364 include \'coupl.inc\'
3365 READLHA = .false.""")
3366 fsock.writelines("""
3367 include \'intparam_definition.inc\'\n
3368+
3369 """)
3370-
3371+
3372+ if self.model['running_elements']:
3373+ running_block = self.model.get_running(self.used_running_key)
3374+ if running_block:
3375+ MUE = [p for p in self.model.get('parameters')[('external',)] if p.lhablock.lower() == 'loop' and tuple(p.lhacode) == (2,)]
3376+
3377+
3378+
3379+ fsock.write_comments('calculate the running parameter')
3380+ fsock.writelines(' if(fixed_extra_scale.and.first) then')
3381+ if self.MUE:
3382+ fsock.writelines(' %s = mue_ref_fixed' % self.MUE.name)
3383+ fsock.writelines(' Gother = SQRT(4.0D0*PI*ALPHAS(mue_ref_fixed))')
3384+ fsock.writelines(' first = .false.')
3385+ for i in range(len(running_block)):
3386+ fsock.writelines(" call C_RUNNING_%s(Gother) ! %s \n" % (i+1,list(running_block[i])))
3387+ fsock.writelines(' elseif(.not.fixed_extra_scale) then')
3388+ fsock.writelines(' Gother = G')
3389+
3390+ if self.MUE:
3391+ fsock.writelines(' %s = mue_over_ref*model_scale' % self.MUE.name)
3392+ else:
3393+ misc.sprint('NO MUE')
3394+ #raise Exception
3395+
3396+ fsock.writelines(' if(mue_over_ref.ne.1d0)then')
3397+ fsock.writelines(' Gother = SQRT(4.0D0*PI*ALPHAS(mue_over_ref*model_scale))')
3398+ fsock.writelines(' endif')
3399+
3400+ for i in range(len(running_block)):
3401+ fsock.writelines(" call C_RUNNING_%s(Gother) ! %s \n" % (i+1,list(running_block[i])))
3402+ fsock.writelines('endif')
3403 nb_coup_indep = 1 + len(self.coups_indep) // nb_def_by_file
3404 nb_coup_dep = 1 + len(self.coups_dep) // nb_def_by_file
3405
3406@@ -7106,9 +7363,13 @@
3407 double precision mu_r2, as2
3408 include \'model_functions.inc\'""")
3409 fsock.writelines("""include \'input.inc\'
3410- include \'coupl.inc\'""")
3411+ include \'coupl.inc\'
3412+ double precision model_scale
3413+ common /model_scale/model_scale
3414+ """)
3415 fsock.writelines("""
3416- if (mu_r2.gt.0d0) MU_R = mu_r2
3417+ if (mu_r2.gt.0d0) MU_R = DSQRT(mu_r2)
3418+ model_scale = DSQRT(mu_r2)
3419 G = SQRT(4.0d0*PI*AS2)
3420 AS = as2
3421
3422@@ -7116,6 +7377,28 @@
3423 """)
3424 fsock.writelines('''\n return \n end\n''')
3425
3426+ # fsock.writelines("""subroutine update_model_to_scale(scale)
3427+ # ! scale in GeV
3428+ # implicit none
3429+ # double precision scale
3430+ # double precision PI
3431+ # double precision alphas
3432+ # external alphas
3433+ # parameter (PI=3.141592653589793d0)
3434+ # double precision mu_r2, as2
3435+ # include \'model_functions.inc\'""")
3436+ # fsock.writelines("""include \'input.inc\'
3437+ # include \'coupl.inc\'
3438+ # """)
3439+ # fsock.writelines("""
3440+ # AS = ALPHAS(scale)
3441+ # AS2 = AS*AS
3442+ # call update_as_param2(scale**2, AS2)
3443+ # """)
3444+ # fsock.writelines('''\n return \n end\n''')
3445+
3446+
3447+
3448 if self.opt['mp']:
3449 fsock.writelines("""subroutine mp_update_as_param()
3450
3451@@ -7137,6 +7420,14 @@
3452
3453 nb_coup_indep = 1 + len(self.coups_indep) // nb_def_by_file
3454 nb_coup_dep = 1 + len(self.coups_dep) // nb_def_by_file
3455+
3456+ if self.model['running_elements']:
3457+ #running_block = self.model.get_running(self.used_running_key)
3458+ if running_block:
3459+ fsock.write_comments('calculate the running parameter')
3460+ for i in range(len(running_block)):
3461+ fsock.writelines(" call MP_C_RUNNING_%s(G) ! %s \n" % (i+1,list(running_block[i])))
3462+
3463
3464 fsock.write_comments('\ncouplings needed to be evaluated points by points\n')
3465
3466@@ -7144,6 +7435,317 @@
3467 ['call mp_coup%s()' % (nb_coup_indep + i + 1) \
3468 for i in range(nb_coup_dep)]))
3469 fsock.writelines('''\n return \n end\n''')
3470+
3471+ if self.model['running_elements'] and running_block:
3472+ self.write_running_blocks(fsock, running_block)
3473+
3474+ def write_running_blocks(self, fsock, running_block):
3475+
3476+ for block_nb, runparams in enumerate(running_block):
3477+ text = self.write_one_running_block(block_nb, runparams)
3478+ fsock.writelines(text)
3479+
3480+
3481+ template_running_gs_gs2 = """
3482+ SUBROUTINE %(mp)sC_RUNNING_%(block_nb)i(GMU)
3483+
3484+ IMPLICIT NONE
3485+ DOUBLE PRECISION PI
3486+ PARAMETER (PI=3.141592653589793D0)
3487+
3488+ include 'input.inc'
3489+ %(mpinput)s
3490+
3491+ include '../cuts.inc'
3492+ INCLUDE 'coupl.inc'
3493+ double precision GMU
3494+
3495+
3496+ double complex mat1(%(size)i,%(size)i), mat2(%(size)i,%(size)i), fullmat(%(size)i,%(size)i), matexp(%(size)i,%(size)i)
3497+ data mat2 /%(mat2)s/
3498+ data mat1 /%(mat1)s/
3499+ double precision C0(%(size)i),Cout(%(size)i)
3500+ data C0 /%(size)i * 0d0/
3501+ logical first
3502+ data first /.true./
3503+ integer i,j,k
3504+ double precision G0,beta0, alphas
3505+ external alphas
3506+ data G0 /0d0/
3507+ double precision r1,r2
3508+ if (first) then
3509+ %(initc0)s
3510+ G0 = SQRT(4.0D0*PI*ALPHAS(mdl__%(scale)s__scale))
3511+ %(check_scale)s
3512+ first = .false.
3513+ endif
3514+ beta0 = 11. - 2./3. * maxjetflavor
3515+ r1 = (1/GMU -1/G0)/ beta0
3516+ r2 = DLOG(G0/GMU)/beta0
3517+ do j=1,%(size)i
3518+ do i=1,%(size)i
3519+ fullmat(j,i) = mat1(j,i) *r1 + mat2(j,i)*r2
3520+ enddo
3521+ enddo
3522+ call c8mat_expm1( %(size)i, fullmat, matexp)
3523+ do j=1,%(size)i
3524+ Cout(j) = 0d0
3525+ enddo
3526+
3527+ do i=1,%(size)i
3528+ do j=1,%(size)i
3529+ Cout(j) = Cout(j) + matexp(j,i) * c0(i)
3530+ enddo
3531+ enddo
3532+
3533+ %(assignc)s
3534+
3535+ return
3536+ end
3537+ """
3538+
3539+ template_running_gs2 = """
3540+ SUBROUTINE %(mp)sC_RUNNING_%(block_nb)i(GMU)
3541+
3542+ IMPLICIT NONE
3543+ DOUBLE PRECISION PI
3544+ PARAMETER (PI=3.141592653589793D0)
3545+
3546+ include '../cuts.inc'
3547+ INCLUDE 'input.inc'
3548+ %(mpinput)s
3549+ INCLUDE 'coupl.inc'
3550+ double precision GMU
3551+
3552+ double complex mat2(%(size)i,%(size)i), fullmat(%(size)i,%(size)i), matexp(%(size)i,%(size)i)
3553+ data mat2 /%(mat2)s/
3554+ double precision C0(%(size)i),Cout(%(size)i)
3555+ data C0 /%(size)i * 0d0/
3556+ logical first
3557+ data first /.true./
3558+ integer i,j,k
3559+ double precision G0,beta0, alphas
3560+ external alphas
3561+ data G0 /0d0/
3562+ double precision r1,r2
3563+ if (first) then
3564+ %(initc0)s
3565+ G0 = SQRT(4.0D0*PI*ALPHAS(mdl__%(scale)s__scale))
3566+ %(check_scale)s
3567+ first = .false.
3568+ endif
3569+ beta0 = 11. - 2./3. * maxjetflavor
3570+ r2 = DLOG(G0/GMU) / beta0
3571+ do j=1,%(size)i
3572+ do i=1,%(size)i
3573+ fullmat(j,i) = mat2(j,i)*r2
3574+ enddo
3575+ enddo
3576+ call c8mat_expm1( %(size)i, fullmat, matexp)
3577+ do j=1,%(size)i
3578+ Cout(j) = 0d0
3579+ enddo
3580+
3581+ do i=1,%(size)i
3582+ do j=1,%(size)i
3583+ Cout(j) = Cout(j) + matexp(j,i) * c0(i)
3584+ enddo
3585+ enddo
3586+
3587+ %(assignc)s
3588+
3589+ return
3590+ end
3591+ """
3592+
3593+ template_running_x3 = """
3594+ SUBROUTINE %(mp)sC_RUNNING_%(block_nb)i(GMU)
3595+
3596+ IMPLICIT NONE
3597+ DOUBLE PRECISION PI
3598+ PARAMETER (PI=3.141592653589793D0)
3599+
3600+ include '../cuts.inc'
3601+ INCLUDE 'input.inc'
3602+ %(mpinput)s
3603+ INCLUDE 'coupl.inc'
3604+ double precision GMU
3605+
3606+ double complex mat3
3607+ data mat3 /%(mat3)s/
3608+ double precision C0
3609+ data C0 /0d0/
3610+ logical first
3611+ data first /.true./
3612+ integer i,j,k
3613+ if (first) then
3614+ C0 = %(mp)s%(initc0)s
3615+ first = .false.
3616+ %(check_scale)s
3617+ endif
3618+
3619+ %(mp)s%(assignc)s = 1/DSQRT( 1/C0/C0 - 2*mat3 *DLOG(MU_R/mdl__%(scale)s__scale))
3620+
3621+ return
3622+ end
3623+ """
3624+
3625+ def get_scales(self):
3626+
3627+ scales = set()
3628+
3629+ for elements in self.model["running_elements"]:
3630+ for params in elements.run_objects:
3631+ sparams = [str(p) for p in params]
3632+ if not any(param in runparams for param in sparams):
3633+ continue
3634+ if 'aS' in sparams or sparams.count('G') == 2:
3635+ to_update = mat2
3636+ prefact = 4*math.pi
3637+ try:
3638+ sparams.remove('aS')
3639+ except:
3640+ sparams.remove('G')
3641+ sparams.remove('G')
3642+ else:
3643+ to_update = mat1
3644+ sparams.remove('G')
3645+ prefact = 16*math.pi**2
3646+
3647+ if len(sparams) == 3:
3648+ if len(set(sparams)) !=1:
3649+ raise Exception( "Not supported type of running")
3650+ mat3 = eval(elements.value)
3651+ continue
3652+ elif len(sparams) !=2:
3653+ raise Exception("Not supported type of running")
3654+ id1 = runparams.index(sparams[0])
3655+ id2 = runparams.index(sparams[1])
3656+ assert to_update[id1][id2] == 0
3657+ to_update[id1][id2] = eval(elements.value)*prefact
3658+ for param in params:
3659+ scales.add(param.lhablock)
3660+
3661+ try:
3662+ scales.remove('SMINPUTS')
3663+ except Exception:
3664+ pass
3665+
3666+ return scales
3667+
3668+
3669+ def write_one_running_block(self, block_nb, runparams):
3670+
3671+ runparams = list(runparams)
3672+
3673+ size = len(runparams)
3674+ mat1=[[0]*size for _ in range(size)]
3675+ mat2=[[0]*size for _ in range(size)]
3676+ mat3=0
3677+ scales = set()
3678+
3679+ for elements in self.model["running_elements"]:
3680+ for params in elements.run_objects:
3681+ sparams = [str(p) for p in params]
3682+ if not any(param in runparams for param in sparams):
3683+ continue
3684+ if 'aS' in sparams or sparams.count('G') == 2:
3685+ to_update = mat2
3686+ prefact = 4*math.pi
3687+ try:
3688+ sparams.remove('aS')
3689+ except:
3690+ sparams.remove('G')
3691+ sparams.remove('G')
3692+ else:
3693+ to_update = mat1
3694+ sparams.remove('G')
3695+ prefact = 16*math.pi**2
3696+
3697+ if len(sparams) == 3:
3698+ if len(set(sparams)) !=1:
3699+ raise Exception( "Not supported type of running")
3700+ mat3 = eval(elements.value)
3701+ continue
3702+ elif len(sparams) !=2:
3703+ raise Exception("Not supported type of running")
3704+ id1 = runparams.index(sparams[0])
3705+ id2 = runparams.index(sparams[1])
3706+ assert to_update[id1][id2] == 0
3707+ to_update[id1][id2] = eval(elements.value)*prefact
3708+ for param in params:
3709+ scales.add(param.lhablock)
3710+
3711+ try:
3712+ scales.remove('SMINPUTS')
3713+ except Exception:
3714+ pass
3715+
3716+ data = {}
3717+ data['block_nb'] = block_nb+1
3718+ data['size'] = size
3719+ data['mp'] = ''
3720+ if mat3:
3721+ template = self.template_running_x3
3722+ data['mat3']
3723+ data['initc0'] = "MDL_%s" % runparams[0]
3724+ data['assignc'] = "MDL_%s" % runparams[0]
3725+ text = template % data
3726+ if self.opt['mp']:
3727+ data['mp'] = 'MP_'
3728+ data['initc0'] = "MP__MDL_%s" % runparams[0]
3729+ data['assignc'] = "MP__MDL_%s" % runparams[0]
3730+ text += template % data
3731+ return text
3732+
3733+ data['initc0'] = "\n".join(["c0(%i) = MDL_%s" % (i+1, name)
3734+ for i, name in enumerate(runparams)])
3735+ data['assignc'] = "\n".join(["MDL_%s = COUT(%i)" % (name,i+1)
3736+ for i, name in enumerate(runparams)])
3737+ data['mp'] = ''
3738+ data['check_scale'] = ''
3739+
3740+ if len(scales) == 1:
3741+ data['scale'] = scales.pop()
3742+ else:
3743+ one_scale = scales.pop()
3744+ data['scale'] = one_scale
3745+ for scale in scales:
3746+ check_scale = """ if (MDL__%(1)s__SCALE.ne.MDL__%(2)s__SCALE) then
3747+ write(*,*) 'ERROR scale %(1)s and %(2)s need to be equal for the running'
3748+ stop 5
3749+ endif
3750+ """
3751+ data['check_scale'] += check_scale % {'1': one_scale, '2': scale}
3752+
3753+ # need to compute the matrices
3754+ # carefull some component are proportional to aS
3755+ # need to convert those to G^2
3756+ # need to be carefull with prefactor included (none yet)
3757+
3758+
3759+
3760+
3761+
3762+ data['mat1'] = ",".join(["%e" % mat1[j][i] for i in range(data['size']) for j in range(data['size'])])
3763+ data['mat2'] = ",".join(["%e" % mat2[j][i] for i in range(data['size']) for j in range(data['size'])])
3764+ data['mpinput'] =''
3765+ if any(mat1[i][j] for i,j in zip(range(size),range(size))):
3766+ template = self.template_running_gs_gs2
3767+ else:
3768+ template = self.template_running_gs2
3769+
3770+ text = template % data
3771+ if self.opt['mp']:
3772+ data['mp'] = 'MP_'
3773+ data['mpinput']="INCLUDE 'mp_input.inc'"
3774+ data['initc0'] = "\n".join(["c0(%i) = MP__MDL_%s" % (i+1, name)
3775+ for i, name in enumerate(runparams)])
3776+ data['assignc'] = "\n".join(["MP__MDL_%s = COUT(%i)" % (name,i+1)
3777+ for i, name in enumerate(runparams)])
3778+ text += template % data
3779+
3780+ return text
3781
3782 def create_couplings_part(self, nb_file, data, dp=True, mp=False):
3783 """ create couplings[nb_file].f containing information coming from data.
3784@@ -8346,9 +8948,12 @@
3785 fsock = self.open('makeinc.inc', comment='#')
3786 text = 'MODEL = couplings.o lha_read.o printout.o rw_para.o'
3787 text += ' model_functions.o '
3788-
3789- nb_coup_indep = 1 + len(self.coups_dep) // 25
3790- nb_coup_dep = 1 + len(self.coups_indep) // 25
3791+ if self.opt['export_format'].startswith('standalone'):
3792+ text += ' alfas_functions.o '
3793+
3794+
3795+ nb_coup_indep = 1 + len(self.coups_dep) // self.nb_def_by_file
3796+ nb_coup_dep = 1 + len(self.coups_indep) // self.nb_def_by_file
3797 couplings_files=['couplings%s.o' % (i+1) \
3798 for i in range(nb_coup_dep + nb_coup_indep) ]
3799 if self.opt['mp']:
3800@@ -8403,6 +9008,25 @@
3801 fsock = self.open('ident_card.dat')
3802
3803 external_param = [format(param) for param in self.params_ext]
3804+ if self.model['running_elements']:
3805+ scales = set()
3806+
3807+ for elements in self.model["running_elements"]:
3808+ for params in elements.run_objects:
3809+ for param in params:
3810+ scales.add(param.lhablock)
3811+
3812+ try:
3813+ scales.remove('SMINPUTS')
3814+ except Exception:
3815+ pass
3816+ #entry should be a parameter ... not a string
3817+ for b in scales:
3818+ param = base_objects.ParamCardVariable(
3819+ 'mdl__%s__scale' % b.lower(),
3820+ 91.188, b, [0])
3821+ external_param.append(format(param))
3822+
3823 fsock.writelines('\n'.join(external_param))
3824
3825 def create_actualize_mp_ext_param_inc(self):
3826@@ -8459,6 +9083,25 @@
3827 res_strings = [format_line(param) \
3828 for param in self.params_ext]
3829
3830+ if self.model['running_elements']:
3831+ scales = set()
3832+
3833+ for elements in self.model["running_elements"]:
3834+ for params in elements.run_objects:
3835+ for param in params:
3836+ scales.add(param.lhablock)
3837+
3838+ try:
3839+ scales.remove('SMINPUTS')
3840+ except Exception:
3841+ pass
3842+ #entry should be a parameter ... not a string
3843+ for b in scales:
3844+ param = base_objects.ParamCardVariable(
3845+ 'mdl__%s__scale' % b,
3846+ 91.188, b, 0)
3847+ res_strings.append(format_line(param))
3848+
3849 # Correct width sign for Majorana particles (where the width
3850 # and mass need to have the same sign)
3851 for particle in self.model.get('particles'):
3852@@ -8614,6 +9257,7 @@
3853 ExporterClass=None
3854 amcatnlo_options = dict(opt)
3855 amcatnlo_options.update(MadLoop_SA_options)
3856+ amcatnlo_options['running'] = cmd._curr_model.get('running_elements')
3857 amcatnlo_options['mp'] = len(cmd._fks_multi_proc.get_virt_amplitudes()) > 0
3858 if not cmd.options['loop_optimized_output']:
3859 logger.info("Writing out the aMC@NLO code")
3860@@ -8637,7 +9281,9 @@
3861 'mp': False,
3862 'sa_symmetry':False,
3863 'model': cmd._curr_model.get('name'),
3864- 'v5_model': False if cmd._model_v4_path else True })
3865+ 'v5_model': False if cmd._model_v4_path else True,
3866+ 'running': cmd._curr_model.get('running_elements'),
3867+ })
3868
3869 format = cmd._export_format #shortcut
3870
3871
3872=== modified file 'madgraph/iolibs/gen_infohtml.py'
3873--- madgraph/iolibs/gen_infohtml.py 2020-05-06 12:09:41 +0000
3874+++ madgraph/iolibs/gen_infohtml.py 2022-05-06 14:56:16 +0000
3875@@ -1,4 +1,4 @@
3876-#! /usr/bin/env python
3877+#! /usr/bin/env python3
3878 ################################################################################
3879 #
3880 # Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors
3881
3882=== modified file 'madgraph/iolibs/template_files/loop_optimized/check_sa.py.inc'
3883--- madgraph/iolibs/template_files/loop_optimized/check_sa.py.inc 2021-01-21 11:53:05 +0000
3884+++ madgraph/iolibs/template_files/loop_optimized/check_sa.py.inc 2022-05-06 14:56:16 +0000
3885@@ -1,4 +1,4 @@
3886-#! /usr/bin/env python
3887+#! /usr/bin/env python3
3888
3889 # This is an example of how to run MadLoop from Python using the f2py compilation of the wrapper file 'f2py_wrapper.f'.
3890
3891
3892=== modified file 'madgraph/iolibs/template_files/madevent_makefile_source'
3893--- madgraph/iolibs/template_files/madevent_makefile_source 2019-03-15 14:20:21 +0000
3894+++ madgraph/iolibs/template_files/madevent_makefile_source 2022-05-06 14:56:16 +0000
3895@@ -22,7 +22,7 @@
3896
3897 # Locally compiled libraries
3898
3899-LIBRARIES=$(LIBDIR)libdsample.$(libext) $(LIBDIR)libgeneric.$(libext)
3900+LIBRARIES=$(LIBDIR)libdsample.$(libext) $(LIBDIR)libgeneric.$(libext)
3901
3902 # Binaries
3903
3904@@ -51,6 +51,8 @@
3905
3906 %(model)s
3907
3908+%(running)s
3909+
3910 $(BINDIR)gen_ximprove: gen_ximprove.o ranmar.o rw_routines.o open_file.o
3911 $(FC) $(LDFLAGS) -o $@ $^
3912 #$(BINDIR)combine_events: $(COMBINE) $(LIBDIR)libmodel.$(libext) $(LIBDIR)libpdf.$(libext) run_card.inc $(LIBDIR)libbias.$(libext)
3913@@ -113,6 +115,7 @@
3914 cd DHELAS; make clean; cd ..
3915 cd CERNLIB; make clean; cd ..
3916 cd MODEL; make clean; cd ..
3917+ if [ -d RUNNING ]; then cd RUNNING; make clean; cd ..; fi
3918 if [ -d $(CUTTOOLSDIR) ]; then cd $(CUTTOOLSDIR); make clean; cd ..; fi
3919 if [ -d $(IREGIDIR) ]; then cd $(IREGIDIR); make clean; cd ..; fi
3920 for i in `ls -d ../SubProcesses/P*`; do cd $$i; make clean; cd -; done;
3921
3922=== modified file 'madgraph/iolibs/template_files/super_auto_dsig_group_v4.inc'
3923--- madgraph/iolibs/template_files/super_auto_dsig_group_v4.inc 2021-07-29 21:30:33 +0000
3924+++ madgraph/iolibs/template_files/super_auto_dsig_group_v4.inc 2022-05-06 14:56:16 +0000
3925@@ -543,6 +543,6 @@
3926 implicit none
3927 integer hel,partid
3928 write(*,*) "this type of pdf is not support with group_subprocess=True. regenerate process with: set group_subprocesses false"
3929- stop 1
3930+ stop 5
3931 return
3932 end
3933\ No newline at end of file
3934
3935=== modified file 'madgraph/loop/loop_base_objects.py'
3936--- madgraph/loop/loop_base_objects.py 2022-03-09 13:00:23 +0000
3937+++ madgraph/loop/loop_base_objects.py 2022-05-06 14:56:16 +0000
3938@@ -1486,6 +1486,7 @@
3939 return ['name', 'particles', 'parameters', 'interactions', 'couplings',
3940 'lorentz','perturbation_couplings','conserved_charge']
3941
3942+
3943 #===============================================================================
3944 # DGLoopLeg
3945 #===============================================================================
3946
3947=== modified file 'madgraph/loop/loop_exporters.py'
3948--- madgraph/loop/loop_exporters.py 2021-11-08 08:25:41 +0000
3949+++ madgraph/loop/loop_exporters.py 2022-05-06 14:56:16 +0000
3950@@ -279,7 +279,7 @@
3951 MLCard.write(pjoin(self.dir_path, 'Cards', 'MadLoopParams_default.dat'))
3952 MLCard.write(pjoin(self.dir_path, 'Cards', 'MadLoopParams.dat'))
3953
3954- def write_f2py_makefile(self):
3955+ def write_f2py_makefile(self, model):
3956 return
3957
3958 def write_f2py_check_sa(self, matrix_element, output_path):
3959
3960=== modified file 'madgraph/madevent/gen_crossxhtml.py'
3961--- madgraph/madevent/gen_crossxhtml.py 2021-02-08 22:58:11 +0000
3962+++ madgraph/madevent/gen_crossxhtml.py 2022-05-06 14:56:16 +0000
3963@@ -771,10 +771,12 @@
3964 self.pgs = []
3965 self.delphes = []
3966 self.shower = []
3967+ self.rivet= []
3968
3969 self.level_modes = ['parton', 'pythia', 'pythia8',
3970 'pgs', 'delphes','reweight','shower',
3971- 'madanalysis5_hadron','madanalysis5_parton']
3972+ 'madanalysis5_hadron','madanalysis5_parton',
3973+ 'rivet']
3974 # data
3975 self.status = ''
3976
3977@@ -874,6 +876,16 @@
3978 misc.glob(pjoin('%s_MA5_PARTON_ANALYSIS_*'%self['tag'],'history.ma5'),html_path):
3979 self.madanalysis5_hadron.append('ma5_card')
3980
3981+ if level in ['rivet','all'] and 'rivet' not in nolevel:
3982+
3983+ if 'yoda' not in self.rivet and os.path.exists(pjoin(path, 'rivet_result.yoda')):
3984+ self.rivet.append('yoda')
3985+ if 'rivethtml' not in self.rivet and os.path.exists(pjoin(path, 'rivet-plots', 'index.html')):
3986+ self.rivet.append('rivethtml')
3987+ if 'contur' not in self.rivet and os.path.exists(pjoin(path, '..','..', 'Analysis','contur','conturPlot','combinedLevels.pdf')):
3988+ self.rivet.append('contur')
3989+
3990+
3991 if level in ['shower','all'] and 'shower' not in nolevel \
3992 and self['run_mode'] != 'madevent':
3993 # this is for hep/top/HwU files from amcatnlo
3994@@ -1017,6 +1029,7 @@
3995 def get_links(self, level):
3996 """ Get the links for a given level"""
3997
3998+
3999 out = ''
4000 if level == 'parton':
4001 if 'gridpack' in self.parton:
4002@@ -1202,6 +1215,15 @@
4003
4004 return out % self
4005
4006+ if level == 'rivet':
4007+ if 'yoda' in self.rivet:
4008+ out += " <a href=\"./Events/%(run_name)s/rivet_result.yoda\">yoda</a>"
4009+ if 'rivethtml' in self.rivet:
4010+ out += " <a href=\"./Events/%(run_name)s/rivet-plots/index.html\">rivet plots</a>"
4011+ if 'contur' in self.rivet:
4012+ out += " <a href=\"./Analysis/contur/conturPlot/combinedLevels.pdf\">contur1</a>"
4013+ out += " <a href=\"./Analysis/contur/conturPlot/dominantPools0CLs.pdf\">contur2</a>"
4014+ return out % self
4015
4016
4017 def get_action(self, ttype, local_dico, runresults):
4018@@ -1318,7 +1340,7 @@
4019 nb_line = 0
4020 self.nb_line = nb_line
4021 for key in ['parton', 'reweight', 'pythia', 'pythia8', 'pgs',
4022- 'delphes', 'shower', 'madanalysis5_hadron']:
4023+ 'delphes', 'shower', 'madanalysis5_hadron','rivet']:
4024 if len(getattr(self, key)):
4025 nb_line += 1
4026 if nb_line ==0 and not os.path.exists(pjoin(self.me_dir, "Events", self["run_name"], "%(run)s_%(tag)s_banner.txt)" % \
4027
4028=== modified file 'madgraph/madevent/gen_ximprove.py'
4029--- madgraph/madevent/gen_ximprove.py 2021-12-03 15:40:10 +0000
4030+++ madgraph/madevent/gen_ximprove.py 2022-05-06 14:56:16 +0000
4031@@ -181,7 +181,9 @@
4032 all_bad_amps_perhel = set()
4033
4034 for line in stdout.splitlines():
4035- if 'GC_' in line:
4036+ if "=" not in line and ":" not in line:
4037+ continue
4038+ if ' GC_' in line:
4039 lsplit = line.split()
4040 if float(lsplit[2]) ==0 == float(lsplit[3]):
4041 zero_gc.append(lsplit[0])
4042
4043=== modified file 'madgraph/madweight/Cards.py'
4044--- madgraph/madweight/Cards.py 2019-04-17 14:39:47 +0000
4045+++ madgraph/madweight/Cards.py 2022-05-06 14:56:16 +0000
4046@@ -1,4 +1,4 @@
4047-#!/usr/bin/env python
4048+#!/usr/bin/env python3
4049 ##########################################################################
4050 ## ##
4051 ## MadWeight ##
4052
4053=== modified file 'madgraph/madweight/MW_driver.py'
4054--- madgraph/madweight/MW_driver.py 2019-04-17 14:39:47 +0000
4055+++ madgraph/madweight/MW_driver.py 2022-05-06 14:56:16 +0000
4056@@ -1,4 +1,4 @@
4057-#! /usr/bin/env python
4058+#! /usr/bin/env python3
4059 ################################################################################
4060 # Copyright (c) 2012 The MadGraph Development team and Contributors
4061 #
4062
4063=== modified file 'madgraph/madweight/MW_info.py'
4064--- madgraph/madweight/MW_info.py 2019-04-17 14:39:47 +0000
4065+++ madgraph/madweight/MW_info.py 2022-05-06 14:56:16 +0000
4066@@ -1,4 +1,4 @@
4067-#!/usr/bin/env python
4068+#!/usr/bin/env python3
4069 ##########################################################################
4070 ## ##
4071 ## MadWeight ##
4072
4073=== modified file 'madgraph/madweight/blob_solution.py'
4074--- madgraph/madweight/blob_solution.py 2019-04-17 14:39:47 +0000
4075+++ madgraph/madweight/blob_solution.py 2022-05-06 14:56:16 +0000
4076@@ -1,4 +1,4 @@
4077-#!/usr/bin/env python
4078+#!/usr/bin/env python3
4079
4080 from __future__ import absolute_import
4081 from __future__ import print_function
4082
4083=== modified file 'madgraph/madweight/change_tf.py'
4084--- madgraph/madweight/change_tf.py 2020-02-27 11:14:44 +0000
4085+++ madgraph/madweight/change_tf.py 2022-05-06 14:56:16 +0000
4086@@ -1,4 +1,4 @@
4087-#!/usr/bin/env python
4088+#!/usr/bin/env python3
4089
4090 #Extension
4091
4092
4093=== modified file 'madgraph/madweight/create_param.py'
4094--- madgraph/madweight/create_param.py 2019-04-17 14:39:47 +0000
4095+++ madgraph/madweight/create_param.py 2022-05-06 14:56:16 +0000
4096@@ -1,4 +1,4 @@
4097-#!/usr/bin/env python
4098+#!/usr/bin/env python3
4099 ##########################################################################
4100 ## ##
4101 ## MadWeight ##
4102
4103=== modified file 'madgraph/madweight/create_run.py'
4104--- madgraph/madweight/create_run.py 2020-03-26 22:18:37 +0000
4105+++ madgraph/madweight/create_run.py 2022-05-06 14:56:16 +0000
4106@@ -1,4 +1,4 @@
4107-#!/usr/bin/env python
4108+#!/usr/bin/env python3
4109
4110 #Extension
4111 from __future__ import absolute_import
4112
4113=== modified file 'madgraph/madweight/diagram_class.py'
4114--- madgraph/madweight/diagram_class.py 2019-04-17 14:39:47 +0000
4115+++ madgraph/madweight/diagram_class.py 2022-05-06 14:56:16 +0000
4116@@ -1,4 +1,4 @@
4117-#!/usr/bin/env python
4118+#!/usr/bin/env python3
4119
4120 from __future__ import absolute_import
4121 from __future__ import print_function
4122
4123=== modified file 'madgraph/madweight/mod_file.py'
4124--- madgraph/madweight/mod_file.py 2019-04-17 14:39:47 +0000
4125+++ madgraph/madweight/mod_file.py 2022-05-06 14:56:16 +0000
4126@@ -1,4 +1,4 @@
4127-#!/usr/bin/env python
4128+#!/usr/bin/env python3
4129 ####################################################################################################
4130 ####################################################################################################
4131 ## ##
4132
4133=== modified file 'madgraph/madweight/substructure_class.py'
4134--- madgraph/madweight/substructure_class.py 2019-04-17 14:39:47 +0000
4135+++ madgraph/madweight/substructure_class.py 2022-05-06 14:56:16 +0000
4136@@ -1,4 +1,4 @@
4137-#!/usr/bin/env python
4138+#!/usr/bin/env python3
4139
4140
4141 from __future__ import absolute_import
4142
4143=== modified file 'madgraph/madweight/verif_event.py'
4144--- madgraph/madweight/verif_event.py 2020-03-26 22:18:37 +0000
4145+++ madgraph/madweight/verif_event.py 2022-05-06 14:56:16 +0000
4146@@ -1,4 +1,4 @@
4147-#!/usr/bin/env python
4148+#!/usr/bin/env python3
4149 ##########################################################################
4150 ## ##
4151 ## MadWeight ##
4152
4153=== modified file 'madgraph/madweight/write_MadWeight.py'
4154--- madgraph/madweight/write_MadWeight.py 2021-08-20 21:39:45 +0000
4155+++ madgraph/madweight/write_MadWeight.py 2022-05-06 14:56:16 +0000
4156@@ -1,4 +1,4 @@
4157-#!/usr/bin/env python
4158+#!/usr/bin/env python3
4159 ##### -*- coding: cp1252 -*-
4160
4161 #Extension
4162
4163=== modified file 'madgraph/various/banner.py'
4164--- madgraph/various/banner.py 2022-02-15 10:26:00 +0000
4165+++ madgraph/various/banner.py 2022-05-06 14:56:16 +0000
4166@@ -342,7 +342,7 @@
4167 self['init'] = '\n'.join(all_lines)
4168
4169
4170- def modify_init_cross(self, cross):
4171+ def modify_init_cross(self, cross, allow_zero=False):
4172 """modify the init information with the associate cross-section"""
4173 assert isinstance(cross, dict)
4174 # assert "all" in cross
4175@@ -366,7 +366,10 @@
4176 new_data += all_lines[i:]
4177 break
4178 if int(pid) not in cross:
4179- raise Exception
4180+ if allow_zero:
4181+ cross[int(pid)] = 0.0 # this is for sub-process with 0 events written in files
4182+ else:
4183+ raise Exception
4184 pid = int(pid)
4185 if float(xsec):
4186 ratio = cross[pid]/float(xsec)
4187@@ -1471,7 +1474,7 @@
4188
4189 if lower_name in self.auto_set:
4190 return 'auto'
4191-
4192+
4193 return dict.__getitem__(self, name.lower())
4194
4195
4196@@ -1490,6 +1493,185 @@
4197 self.__setitem__(name, value, change_userdefine=user, raiseerror=raiseerror)
4198
4199
4200+class RivetCard(ConfigFile):
4201+
4202+ def default_setup(self):
4203+ """initialize the directory to the default value"""
4204+ self.add_param('analysis', [], typelist=str)
4205+ self.add_param('run_rivet_later', False)
4206+ self.add_param('run_contur', False)
4207+ self.add_param('draw_rivet_plots', False)
4208+ self.add_param('draw_contur_heatmap', True)
4209+ self.add_param('xaxis_var', "default")
4210+ self.add_param('xaxis_relvar', "default")
4211+ self.add_param('xaxis_label', "default")
4212+ self.add_param('xaxis_log', False)
4213+ self.add_param('yaxis_var', "default")
4214+ self.add_param('yaxis_relvar', "default")
4215+ self.add_param('yaxis_label', "default")
4216+ self.add_param('yaxis_log', False)
4217+
4218+ # ================================================================
4219+ # hidden (users don't really have to touch these most of the time)
4220+ self.add_param('contur_ra', "default")
4221+ self.add_param('rivet_sqrts', "default")
4222+ self.add_param('weight_name', "default")
4223+ self.add_param('rivet_add', 'default')
4224+ self.add_param('contur_add', 'default')
4225+ # ================================================================
4226+
4227+ def read(self, finput):
4228+
4229+ if isinstance(finput, str):
4230+ if "\n" in finput:
4231+ finput = finput.split('\n')
4232+ elif os.path.isfile(finput):
4233+ finput = open(finput)
4234+ else:
4235+ raise Exception("No such file %s" % finput)
4236+
4237+ for line in finput:
4238+ if '#' in line:
4239+ line = line.split('#',1)[0]
4240+
4241+ if '!' in line:
4242+ line = line.split('#',1)[0]
4243+
4244+ if not line:
4245+ continue
4246+
4247+ if '=' in line:
4248+ key, value = line.split('=',1)
4249+ if key.strip() in ["xaxis_var", "xaxis_relvar", "xaxis_label",\
4250+ "yaxis_var", "yaxis_relvar", "yaxis_label",\
4251+ "rivet_add", "contur_add"]:
4252+ value = value.lower()
4253+ if value.strip() == "default":
4254+ value = ""
4255+ self[key.strip()] = value.strip()
4256+
4257+ def write(self, output_file, template=None):
4258+
4259+ if not template:
4260+ if not MADEVENT:
4261+ template = pjoin(MG5DIR, 'Template', 'LO', 'Cards', 'rivet_card_default.dat')
4262+ else:
4263+ template = pjoin(MEDIR, 'Cards', 'rivet_card_default.dat')
4264+
4265+ text = ""
4266+ for line in open(template,'r'):
4267+ nline = line.split('#')[0]
4268+ nline = nline.split('!')[0]
4269+ comment = line[len(nline):]
4270+ nline = nline.split('=')
4271+ if len(nline) != 2:
4272+ text += line
4273+ elif nline[0].strip() in list(self.keys()):
4274+ text += '%s\t= %s %s\n' % (nline[0], self[nline[0].strip()], comment)
4275+ else:
4276+ logger.info('Adding missing parameter %s to current rivet_card (with default value)' % nline[1].strip())
4277+ text += line
4278+
4279+ if isinstance(output_file, str):
4280+ fsock = open(output_file,'w')
4281+ else:
4282+ fsock = output_file
4283+
4284+ fsock.write(text)
4285+ fsock.close()
4286+
4287+ def getAnalysisList(self, runcard):
4288+
4289+ '''
4290+ This function defines/parses which analysis to run with Rivet
4291+ If not given and CONTUR is turned off : electrons, muons, taus, met, jets
4292+ on : check the beam energy and run all available analyses with same beam E
4293+ '''
4294+
4295+ analysis_list = []
4296+ rivet_sqrts = int(runcard['ebeam1']) + int(runcard['ebeam2'])
4297+ self["rivet_sqrts"] = str(rivet_sqrts)
4298+
4299+ if len(self["analysis"]) == 1:
4300+ this_analysis = self["analysis"][0]
4301+
4302+ if this_analysis == "default" or this_analysis == None or this_analysis == "":
4303+ if not self["run_contur"]:
4304+ analysis_list.append("MC_ELECTRONS")
4305+ analysis_list.append("MC_MUONS")
4306+ analysis_list.append("MC_TAUS")
4307+ analysis_list.append("MC_MET")
4308+ analysis_list.append("MC_JETS")
4309+ else:
4310+ if not ((runcard['lpp1'] == 1) and (runcard['lpp2'] == 1)):
4311+ raise MadGraph5Error("Incorrect beam type, lpp1 and lpp2 both should be 1 (proton)")
4312+ ebeamsLHC = [3500, 4000, 6500]
4313+
4314+ if ((int(runcard['ebeam1']) in ebeamsLHC) and (int(runcard['ebeam2']) in ebeamsLHC)):
4315+ if int(runcard['ebeam1']) == int(runcard['ebeam2']):
4316+ analysis_list.append("$CONTUR_RA{0}TeV".format(int(rivet_sqrts/1000)))
4317+ self["contur_ra"] = "{0}TeV".format(int(rivet_sqrts/1000))
4318+ else:
4319+ raise MadGraph5Error("Incorrect beam energy, ebeam1 and ebeam2 should be equal but\n\
4320+ ebeam1 = {0} and ebeam2 = {1}".format(runcard['ebeam1'], runcard['ebeam2']))
4321+ else:
4322+ raise MadGraph5Error("Incorrect beam energy, ebeam1 and ebeam2 should be {0}".format(ebeamsLHC))
4323+
4324+ else:
4325+ analysis_list.append(this_analysis)
4326+
4327+ else:
4328+ for this_analysis in self["analysis"]:
4329+ analysis_list.append(this_analysis)
4330+
4331+ return analysis_list
4332+
4333+ def setWeightName(self, runcard, py8card):
4334+
4335+ '''
4336+ Give weight names in case the jet merging is used to use for Rivet runs
4337+ '''
4338+
4339+ if self['weight_name'] == "default":
4340+ if runcard['ickkw'] == 0:
4341+ self['weight_name'] = "None"
4342+ else:
4343+ self['weight_name'] = "Weight_MERGING={0}".str(round(py8card['JetMatching:qCut'],3))
4344+
4345+ def setRelevantParamCard(self, f_params, f_relparams):
4346+
4347+ '''
4348+ Used for Contur
4349+ Used for cases when user wants to scan a BSM parameter that is not a value directly modifiable from UFO
4350+ e.g. Wants to scan the <<square of coupling>> when UFO only has <<coupling>>
4351+ '''
4352+
4353+ exec_line = "import math; "
4354+ for l_param in f_params.readlines():
4355+ exec_line = exec_line + l_param.strip() + "; "
4356+ f_relparams.write(l_param.strip()+"\n")
4357+
4358+ if self['xaxis_relvar']:
4359+ xexec_dict = {}
4360+ xexec_line = exec_line + "xaxis_relvar = " + self['xaxis_relvar']
4361+ exec(xexec_line, locals(), xexec_dict)
4362+ if self['xaxis_label'] == "":
4363+ self['xaxis_label'] = "xaxis_relvar"
4364+ f_relparams.write("{0} = {1}\n".format(self['xaxis_label'], xexec_dict['xaxis_relvar']))
4365+ else:
4366+ if self['xaxis_label'] == "":
4367+ self['xaxis_label'] = self['xaxis_var']
4368+
4369+ if self['yaxis_relvar']:
4370+ yexec_dict = {}
4371+ yexec_line = exec_line + "yaxis_relvar = " + self['yaxis_relvar']
4372+ exec(yexec_line, locals(), yexec_dict)
4373+ if self['yaxis_label'] == "":
4374+ self['yaxis_label'] = "yaxis_relvar"
4375+ f_relparams.write("{0} = {1}\n".format(self['yaxis_label'], yexec_dict['yaxis_relvar']))
4376+ else:
4377+ if self['yaxis_label'] == "":
4378+ self['yaxis_label'] = self['yaxis_var']
4379
4380 class ProcCharacteristic(ConfigFile):
4381 """A class to handle information which are passed from MadGraph to the madevent
4382@@ -1667,7 +1849,7 @@
4383 # Select the HepMC output. The user can prepend 'fifo:<optional_fifo_path>'
4384 # to indicate that he wants to pipe the output. Or /dev/null to turn the
4385 # output off.
4386- self.add_param("HEPMCoutput:file", 'auto')
4387+ self.add_param("HEPMCoutput:file", 'hepmc.gz')
4388
4389 # Hidden parameters always written out
4390 # ====================================
4391@@ -2635,12 +2817,12 @@
4392 text = text % data
4393 else:
4394 text = ""
4395- for line in open(template,'r'):
4396+ for line in open(template,'r'):
4397 nline = line.split('#')[0]
4398 nline = nline.split('!')[0]
4399 comment = line[len(nline):]
4400 nline = nline.rsplit('=',1)
4401- if python_template and nline[0].startswith('$'):
4402+ if python_template and nline[0].strip().startswith('$'):
4403 block_name = nline[0][1:].strip()
4404 this_group = [b for b in self.blocks if b.name == block_name]
4405 if not this_group:
4406@@ -3136,10 +3318,21 @@
4407 %(ptlund)s = ptlund
4408 %(pdgs_for_merging_cut)s = pdgs_for_merging_cut ! PDGs for two cuts above
4409 """
4410-template_off = ""
4411-
4412-ckkw_block = RunBlock('ckkw', template_on=template_on, template_off=template_off)
4413-
4414+
4415+ckkw_block = RunBlock('ckkw', template_on=template_on, template_off="")
4416+
4417+# Running -----------------------------------------------------------------------------------------
4418+template_on = \
4419+"""#***********************************************************************
4420+# CONTROL The extra running scale (not QCD) *
4421+# Such running is NOT include in systematics computation *
4422+#***********************************************************************
4423+ %(fixed_extra_scale)s = fixed_extra_scale ! False means dynamical scale
4424+ %(mue_ref_fixed)s = mue_ref_fixed ! scale to use if fixed scale mode
4425+ %(mue_over_ref)s = mue_over_ref ! ratio to mur if dynamical scale
4426+"""
4427+
4428+running_block = RunBlock('RUNNING', template_on=template_on, template_off="")
4429
4430 # Phase-Space Optimization ------------------------------------------------------------------------------------
4431 template_on = \
4432@@ -3159,6 +3352,7 @@
4433 %(aloha_flag)s = aloha_flag ! fortran optimization flag for aloha function. Suggestions: '-ffast-math'
4434 %(matrix_flag)s = matrix_flag ! fortran optimization flag for matrix.f function. Suggestions: '-O3'
4435 """
4436+
4437 template_off = '# To see advanced option for Phase-Space optimization: type "update psoptim"'
4438
4439 psoptim_block = RunBlock('psoptim', template_on=template_on, template_off=template_off)
4440@@ -3293,7 +3487,7 @@
4441
4442 blocks = [heavy_ion_block, beam_pol_block, syscalc_block, ecut_block,
4443 frame_block, eva_scale_block, mlm_block, ckkw_block, psoptim_block,
4444- pdlabel_block, fixedfacscale]
4445+ pdlabel_block, fixedfacscale, running_block]
4446
4447 def default_setup(self):
4448 """default value for the run_card.dat"""
4449@@ -3338,11 +3532,14 @@
4450 self.add_param("fixed_fac_scale", False, hidden=True, include=False, comment="define if the factorization scale is fixed or not. You can define instead fixed_fac_scale1 and fixed_fac_scale2 if you want to make that choice per beam")
4451 self.add_param("fixed_fac_scale1", False, hidden=True)
4452 self.add_param("fixed_fac_scale2", False, hidden=True)
4453+ self.add_param("fixed_extra_scale", False, hidden=True)
4454 self.add_param("scale", 91.1880)
4455 self.add_param("dsqrt_q2fact1", 91.1880, fortran_name="sf1")
4456 self.add_param("dsqrt_q2fact2", 91.1880, fortran_name="sf2")
4457+ self.add_param("mue_ref_fixed", 91.1880, hidden=True)
4458 self.add_param("dynamical_scale_choice", -1, comment="\'-1\' is based on CKKW back clustering (following feynman diagram).\n \'1\' is the sum of transverse energy.\n '2' is HT (sum of the transverse mass)\n '3' is HT/2\n '4' is the center of mass energy\n",
4459 allowed=[-1,0,1,2,3,4])
4460+ self.add_param("mue_over_ref", 1.0, hidden=True, comment='ratio mu_other/mu for dynamical scale')
4461 self.add_param("ievo_eva",0,hidden=True, allowed=[0,1],fortran_name="ievo_eva",
4462 comment='eva: 0 for EW pdf muf evolution by q^2; 1 for evo by pT^2')
4463
4464@@ -4069,6 +4266,13 @@
4465 logger.critical("MLM matching/merging not compatible with the model! You need to use another method to remove the double counting!")
4466 self['ickkw'] = 0
4467
4468+ if 'fix_scale' in proc_characteristic['limitations']:
4469+ self['fixed_ren_scale'] = 1
4470+ self['fixed_fac_scale'] = 1
4471+ if self['ickkw'] == 1:
4472+ logger.critical("MLM matching/merging not compatible with the model! You need to use another method to remove the double counting!")
4473+ self['ickkw'] = 0
4474+
4475 # define class of particles present to hide all the cuts associated to
4476 # not present class
4477 cut_class = collections.defaultdict(int)
4478@@ -4100,8 +4304,12 @@
4479 cut_class[key] = max(cut_class[key], nb)
4480 self.cut_class = dict(cut_class)
4481 self.cut_class[''] = True #avoid empty
4482-
4483-
4484+
4485+ # If model has running functionality add the additional parameter
4486+ model = proc_def[0][0].get('model')
4487+ if model['running_elements']:
4488+ self.display_block.append('RUNNING')
4489+
4490 def write(self, output_file, template=None, python_template=False,
4491 **opt):
4492 """Write the run_card in output_file according to template
4493@@ -4453,6 +4661,10 @@
4494 def get_import(input, type=None):
4495 """ Generates the MA5 import commands for that event file. """
4496 dataset_name = os.path.basename(input).split('.')[0]
4497+ if dataset_name == "unweighted_events":
4498+ split = input.split(os.sep)
4499+ if 'Events' in split:
4500+ dataset_name = split[split.index('Events')+1]
4501 res = ['import %s as %s'%(input, dataset_name)]
4502 if not type is None:
4503 res.append('set %s.type = %s'%(dataset_name, type))
4504@@ -4475,6 +4687,9 @@
4505 inputs_load = []
4506 for input in inputs:
4507 inputs_load.extend(get_import(input))
4508+
4509+ if len(inputs) > 1:
4510+ inputs_load.append('set main.stacking_method = superimpose')
4511
4512 submit_command = 'submit %s'%submit_folder+'_%s'
4513
4514@@ -4568,11 +4783,24 @@
4515
4516 return cmds_list
4517
4518+# Running -----------------------------------------------------------------------------------------
4519+template_on = \
4520+"""#***********************************************************************
4521+# CONTROL The extra running scale (not QCD) *
4522+# Such running is NOT include in systematics computation *
4523+#***********************************************************************
4524+ %(mue_ref_fixed)s = mue_ref_fixed ! scale to use if fixed scale mode
4525+"""
4526+running_block_nlo = RunBlock('RUNNING', template_on=template_on, template_off="")
4527+
4528 class RunCardNLO(RunCard):
4529 """A class object for the run_card for a (aMC@)NLO pocess"""
4530
4531 LO = False
4532
4533+ blocks = [running_block_nlo]
4534+
4535+
4536 def default_setup(self):
4537 """define the default value"""
4538
4539@@ -4603,10 +4831,12 @@
4540 self.add_param('shower_scale_factor',1.0)
4541 self.add_param('fixed_ren_scale', False)
4542 self.add_param('fixed_fac_scale', False)
4543+ self.add_param('fixed_extra_scale', True, hidden=True, system=True) # set system since running from Ellis-Sexton scale not implemented
4544 self.add_param('mur_ref_fixed', 91.118)
4545 self.add_param('muf1_ref_fixed', -1.0, hidden=True)
4546 self.add_param('muf_ref_fixed', 91.118)
4547 self.add_param('muf2_ref_fixed', -1.0, hidden=True)
4548+ self.add_param('mue_ref_fixed', 91.118, hidden=True)
4549 self.add_param("dynamical_scale_choice", [-1],fortran_name='dyn_scale', comment="\'-1\' is based on CKKW back clustering (following feynman diagram).\n \'1\' is the sum of transverse energy.\n '2' is HT (sum of the transverse mass)\n '3' is HT/2")
4550 self.add_param('fixed_qes_scale', False, hidden=True)
4551 self.add_param('qes_ref_fixed', -1.0, hidden=True)
4552@@ -4614,6 +4844,7 @@
4553 self.add_param('muf_over_ref', 1.0)
4554 self.add_param('muf1_over_ref', -1.0, hidden=True)
4555 self.add_param('muf2_over_ref', -1.0, hidden=True)
4556+ self.add_param('mue_over_ref', 1.0, hidden=True, system=True) # forbid the user to modigy due to incorrect handling of the Ellis-Sexton scale
4557 self.add_param('qes_over_ref', -1.0, hidden=True)
4558 self.add_param('reweight_scale', [True], fortran_name='lscalevar')
4559 self.add_param('rw_rscale_down', -1.0, hidden=True)
4560@@ -4894,7 +5125,7 @@
4561 else:
4562 template = pjoin(MEDIR, 'Cards', 'run_card_default.dat')
4563 python_template = False
4564-
4565+
4566 super(RunCardNLO, self).write(output_file, template=template,
4567 python_template=python_template, **opt)
4568
4569@@ -4936,6 +5167,11 @@
4570 # check for tagged photons
4571 tagged_particles = set()
4572
4573+ # If model has running functionality add the additional parameter
4574+ model = proc_def[0].get('model')
4575+ if model['running_elements']:
4576+ self.display_block.append('RUNNING')
4577+
4578 # Check if need matching
4579 min_particle = 99
4580 max_particle = 0
4581@@ -4992,7 +5228,6 @@
4582
4583
4584
4585-
4586 class MadLoopParam(ConfigFile):
4587 """ a class for storing/dealing with the file MadLoopParam.dat
4588 contains a parser to read it, facilities to write a new file,...
4589
4590=== modified file 'madgraph/various/combine_plots.py'
4591--- madgraph/various/combine_plots.py 2019-04-17 14:39:47 +0000
4592+++ madgraph/various/combine_plots.py 2022-05-06 14:56:16 +0000
4593@@ -1,4 +1,4 @@
4594-#!/usr/bin/env python
4595+#!/usr/bin/env python3
4596 ################################################################################
4597 #
4598 # Copyright (c) 2013 The MadGraph5_aMC@NLO Development team and Contributors
4599
4600=== modified file 'madgraph/various/histograms.py'
4601--- madgraph/various/histograms.py 2021-12-03 15:40:10 +0000
4602+++ madgraph/various/histograms.py 2022-05-06 14:56:16 +0000
4603@@ -1,4 +1,4 @@
4604-#! /usr/bin/env python2
4605+#! /usr/bin/env python3
4606 ################################################################################
4607 #
4608 # Copyright (c) 2010 The MadGraph5_aMC@NLO Development team and Contributors
4609
4610=== modified file 'madgraph/various/lhe_parser.py'
4611--- madgraph/various/lhe_parser.py 2022-03-18 09:02:34 +0000
4612+++ madgraph/various/lhe_parser.py 2022-05-06 14:56:16 +0000
4613@@ -494,18 +494,18 @@
4614 if self.banner:
4615 try:
4616 import internal
4617- except:
4618- import madgraph.various.banner as banner_module
4619- else:
4620+ import internal.banner as banner_module
4621+ except ImportError:
4622 try:
4623- import internal.banner as banner_module
4624- except:
4625+ import madgraph.various.banner as banner_module
4626+ except ImportError:
4627 logger.debug("no banner module found")
4628 banner_module = None
4629+
4630 if banner_module and not isinstance(self.banner, banner_module.Banner):
4631 banner = self.get_banner()
4632 # 1. modify the cross-section
4633- banner.modify_init_cross(cross)
4634+ banner.modify_init_cross(cross, allow_zero=True) # for few event cross might miss input
4635 # 3. add information about change in weight
4636 banner["unweight"] = "unweighted by %s" % unwgt_name
4637 else:
4638@@ -1155,6 +1155,7 @@
4639 all_wgt = all_wgt[-nb_keep:]
4640 self.seek(0)
4641 self._configure = True
4642+
4643 return all_wgt, sum_cross, total_event
4644
4645 def configure(self):
4646@@ -2366,6 +2367,128 @@
4647
4648 return out
4649
4650+
4651+ def get_all_momenta(self, get_order, allow_reversed=True, debug_output=None):
4652+ """ same as get_momenta but return all valid permutation of the final state
4653+ where identical particle does NOT have the same parent
4654+ for easier development debug output allow to return internal variable for the unittest to check
4655+ """
4656+
4657+
4658+ p = self.get_momenta(get_order, allow_reversed)
4659+
4660+ nbin = len(get_order[0])
4661+ final = get_order[1]
4662+ data = {} # dict will be {pdg: {(m1,m2): [position1, position2]}} position are position in p
4663+ for i, part in enumerate(self):
4664+ pdg = part.pid
4665+ if part.status != 1:
4666+ continue
4667+ try:
4668+ m1 = part.mother1.event_id
4669+ except AttributeError:
4670+ m1 = 0
4671+ try:
4672+ m2 = part.mother2.event_id
4673+ except AttributeError:
4674+ m2 = 0
4675+ M = (m1,m2)
4676+ if pdg in data:
4677+ max_prev = max(k+1 for N in data[pdg] for k in data[pdg][N] ) - nbin
4678+ if M in data[pdg]:
4679+ data[pdg][M].append(nbin+final.index(pdg,max_prev))
4680+ else:
4681+ data[pdg][M] = [nbin+final.index(pdg, max_prev)]
4682+ else:
4683+ data[pdg] = {M:[nbin+final.index(pdg)]}
4684+
4685+ # for unnittest
4686+ if debug_output == 1:
4687+ return data
4688+
4689+ # check which pdg to permutate
4690+ # need to permutate pdg code where multiple M are present
4691+ perms_perid = {}
4692+ for pdg in data:
4693+ if len(data[pdg]) == 1:
4694+ mother = list(data[pdg].keys())[0]
4695+ perms_perid[pdg] = [[(i,i) for i in data[pdg][mother]]]
4696+ else:
4697+ positions = []
4698+ mapping = [] #mapping from position to the class
4699+ for mother in data[pdg]:
4700+ for val in data[pdg][mother]:
4701+ mapping.append(mother)
4702+ positions.append(val)
4703+ all_perms = Event.get_permutation(positions, mapping)
4704+ perms_perid[pdg] = [[(pos, positions[i]) for i,pos in enumerate(perm)] for perm in all_perms]
4705+
4706+ if debug_output == 2:
4707+ return perms_perid
4708+
4709+ all_perms = []
4710+ import itertools
4711+ for i in itertools.product(*perms_perid.values()):
4712+ perm_pos = dict(sum(i,[]))
4713+ new_p = [[0,0,0,0]]*len(p)
4714+ new_p[:nbin] = p[:nbin]
4715+ for i,j in perm_pos.items():
4716+ new_p[i] = p[j]
4717+ all_perms.append(new_p)
4718+
4719+ return all_perms
4720+
4721+
4722+
4723+ @staticmethod
4724+ def equiv_sequence(l1,l2, mapping):
4725+ """check if two sequence are equivalent
4726+ mapping is a dictionary taking an index and return an identifier.
4727+ The two list are consider equivalent if the total content associated to an identifier
4728+ is the same (up to ordering)
4729+ so (3,4,5) and (4,3,5) are the same for mapping={0:"a",1:"a",2:"b"}
4730+ since a is assocated to 3,4 in both case (and b to 5 in each case
4731+ but (3,4,5) and (3,5,4) are not the same because b has 5 in one case and 4 in the second
4732+ """
4733+ content1 = collections.defaultdict(set)
4734+ content2 = collections.defaultdict(set)
4735+ for i in range(len(l1)):
4736+ content1[mapping[i]].add(l1[i])
4737+ content2[mapping[i]].add(l2[i])
4738+
4739+ for key in content1:
4740+ if content1[key] != content2[key]:
4741+ return False
4742+ return True
4743+
4744+ @staticmethod
4745+ def get_permutation(orig, belong):
4746+ """
4747+ orig is the position of the various particle to permutate
4748+ belong is the class to which they belong
4749+ so for [3,4,5] and ["A", "A" , "b"] the code will return
4750+ three permutation of orig (like)
4751+ [3,4,5], [3,5,4], [4,5,3]
4752+ """
4753+
4754+ import itertools
4755+
4756+ assert(len(orig) == len(belong))
4757+ invert = {}
4758+ for i in range(len(orig)):
4759+ invert[i] = belong[i]
4760+
4761+ allperms = []
4762+ for perm in itertools.permutations(orig):
4763+ if not any(Event.equiv_sequence(perm, prev, invert) for prev in allperms):
4764+ allperms.append(perm)
4765+ return allperms
4766+
4767+
4768+
4769+
4770+
4771+
4772
4773 def get_scale(self,type):
4774
4775@@ -2973,6 +3096,15 @@
4776 out[position] = (part.E, part.px, part.py, part.pz)
4777
4778 return out
4779+
4780+ def get_all_momenta(self, get_order, allow_reversed=True, debug_output=None):
4781+ """ same as get_momenta but return all valid permutation of the final state
4782+ where identical particle does NOT have the same parent
4783+ for easier development debug output allow to return internal variable for the unittest to check
4784+ """
4785+
4786+
4787+ return [self.get_momenta(get_order, allow_reversed)]
4788
4789
4790 def get_helicity(self, *args):
4791
4792=== modified file 'madgraph/various/misc.py'
4793--- madgraph/various/misc.py 2021-12-08 16:35:51 +0000
4794+++ madgraph/various/misc.py 2022-05-06 14:56:16 +0000
4795@@ -466,7 +466,7 @@
4796
4797 if 'copy_function' not in opts:
4798 opts['copy_function'] = shutil.copy
4799- return misc.copytree(*args, **opts)
4800+ return shutil.copytree(*args, **opts)
4801
4802 #===============================================================================
4803 # Compiler which returns smart output error in case of trouble
4804@@ -788,6 +788,7 @@
4805 except Exception as error:
4806 # Cannot probe the compiler, assume not clang then
4807 return False
4808+
4809 output = output.decode(errors='ignore')
4810
4811 return 'LLVM' in str(output) or "clang" in str(output)
4812@@ -1727,25 +1728,31 @@
4813 # except psutil.error.NoSuchProcess:
4814 # pass
4815
4816-## Define apple_notify (in a way which is system independent
4817-class Applenotification(object):
4818+## Define system_notify (in a way which is system independent
4819+class Notification(object):
4820
4821 def __init__(self):
4822 self.init = False
4823 self.working = True
4824
4825- def load_notification(self):
4826- try:
4827- import Foundation
4828- import objc
4829- self.NSUserNotification = objc.lookUpClass('NSUserNotification')
4830- self.NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
4831- except:
4832- self.working=False
4833- if which('osascript'):
4834- self.working = 'osascript'
4835- return
4836- self.working=True
4837+ def load_notification(self):
4838+ self.init = True
4839+ self.working = False
4840+ if sys.platform == 'darwin':
4841+ try:
4842+ import Foundation
4843+ import objc
4844+ self.NSUserNotification = objc.lookUpClass('NSUserNotification')
4845+ self.NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
4846+ self.working = "Foundation"
4847+ except:
4848+ if which('osascript'):
4849+ self.working = 'osascript'
4850+ return
4851+ elif sys.platform == 'linux':
4852+ if which('notify-send'):
4853+ self.working = 'notify-send'
4854+
4855
4856 def __call__(self,subtitle, info_text, userInfo={}):
4857
4858@@ -1753,7 +1760,7 @@
4859 self.load_notification()
4860 if not self.working:
4861 return
4862- elif self.working is True:
4863+ elif self.working == "Foundation":
4864 try:
4865 notification = self.NSUserNotification.alloc().init()
4866 notification.setTitle_('MadGraph5_aMC@NLO')
4867@@ -1766,7 +1773,7 @@
4868 self.NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
4869 except:
4870 pass
4871-
4872+
4873 elif self.working=='osascript':
4874 try:
4875 os.system("""
4876@@ -1774,10 +1781,16 @@
4877 """.format(info_text, subtitle))
4878 except:
4879 pass
4880-
4881-
4882-
4883-apple_notify = Applenotification()
4884+
4885+ elif self.working == 'notify-send':
4886+ try:
4887+ os.system(""" notify-send "MadGraph5_aMC@NLO" "{}" &> /dev/null """.format(info_text,subtitle))
4888+ except:
4889+ pass
4890+
4891+
4892+
4893+system_notify = Notification()
4894
4895 class EasterEgg(object):
4896
4897@@ -1902,7 +1915,7 @@
4898
4899 if muted:
4900 if not EasterEgg.done_notification:
4901- apple_notify('On April first','turn up your volume!')
4902+ system_notify('On April first','turn up your volume!')
4903 EasterEgg.done_notification = True
4904 else:
4905 os.system('say %s' % msg)
4906@@ -2112,6 +2125,12 @@
4907 use_lhapdf=False
4908 return False
4909 else:
4910+ if sys.platform != "darwin":
4911+ if not 'LD_LIBRARY_PATH' in os.environ:
4912+ os.environ['LD_LIBRARY_PATH'] = lhapdf_libdir
4913+ else:
4914+ os.environ['LD_LIBRARY_PATH'] = '%s:%s' %(lhapdf_libdir,os.environ['LD_LIBRARY_PATH'])
4915+
4916 try:
4917 candidates=[dirname for dirname in os.listdir(lhapdf_libdir) \
4918 if os.path.isdir(os.path.join(lhapdf_libdir,dirname))]
4919
4920=== modified file 'madgraph/various/plot_djrs.py'
4921--- madgraph/various/plot_djrs.py 2019-04-17 14:39:47 +0000
4922+++ madgraph/various/plot_djrs.py 2022-05-06 14:56:16 +0000
4923@@ -1,4 +1,4 @@
4924-#! /usr/bin/env python
4925+#! /usr/bin/env python3
4926 ################################################################################
4927 #
4928 # Copyright (c) 2010 The MadGraph5_aMC@NLO Development team and Contributors
4929
4930=== modified file 'models/__init__.py'
4931--- models/__init__.py 2021-05-23 07:47:20 +0000
4932+++ models/__init__.py 2022-05-06 14:56:16 +0000
4933@@ -65,7 +65,7 @@
4934
4935 # remove any link to previous model
4936 for name in ['particles', 'object_library', 'couplings', 'function_library', 'lorentz', 'parameters', 'vertices', 'coupling_orders', 'write_param_card',
4937- 'CT_couplings', 'CT_vertices', 'CT_parameters']:
4938+ 'CT_couplings', 'CT_vertices', 'CT_parameters', 'running']:
4939 try:
4940 del sys.modules[name]
4941 except Exception:
4942
4943=== modified file 'models/check_param_card.py'
4944--- models/check_param_card.py 2021-11-02 14:19:01 +0000
4945+++ models/check_param_card.py 2022-05-06 14:56:16 +0000
4946@@ -270,8 +270,8 @@
4947 self.name += ' %s' % data[2]
4948 elif len(data) == 4 and data[2] == 'q=':
4949 #the last part should be of the form Q=
4950- self.scale = float(data[3])
4951-
4952+ self.scale = float(data[3])
4953+
4954 return self
4955
4956 def keys(self):
4957@@ -561,6 +561,13 @@
4958 lhacode = ' '.join([str(i) for i in lhacode])
4959 diff += 'set param_card %s %s %s # orig: %s\n' % \
4960 (blockname, lhacode , new_value, value)
4961+ value = block.scale
4962+ new_value = new_card[blockname].scale
4963+ if not misc.equal(value, new_value, 6, zero_limit=False):
4964+ diff += 'set param_card %s scale %s # orig: %s\n' % \
4965+ (blockname , new_value, value)
4966+
4967+
4968 return diff
4969
4970
4971@@ -622,10 +629,18 @@
4972
4973 def write_inc_file(self, outpath, identpath, default, need_mp=False):
4974 """ write a fortran file which hardcode the param value"""
4975-
4976+
4977 self.secure_slha2(identpath)
4978-
4979-
4980+ input_inc = pjoin(os.path.dirname(outpath),'MODEL', 'input.inc')
4981+
4982+ #check if we need to write the value of scale for some block
4983+ if os.path.exists(input_inc):
4984+ text = open(input_inc).read()
4985+ scales = list(set(re.findall('mdl__(\w*)__scale', text, re.I)))
4986+ else:
4987+ scales = []
4988+
4989+
4990 fout = file_writers.FortranWriter(outpath)
4991 defaultcard = ParamCard(default)
4992 for line in open(identpath):
4993@@ -641,14 +656,28 @@
4994 try:
4995 value = self[block].get(tuple(lhaid)).value
4996 except KeyError:
4997- value =defaultcard[block].get(tuple(lhaid)).value
4998- logger.warning('information about \"%s %s" is missing using default value: %s.' %\
4999+ if lhaid == [0]:
5000+ try:
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: