Merge lp:~olivier-mattelaer/mg5amcnlo/2.5.3 into lp:mg5amcnlo/lts

Proposed by Olivier Mattelaer
Status: Merged
Merged at revision: 270
Proposed branch: lp:~olivier-mattelaer/mg5amcnlo/2.5.3
Merge into: lp:mg5amcnlo/lts
Diff against target: 8933 lines (+3590/-1194)
80 files modified
MadSpin/decay.py (+283/-6)
MadSpin/interface_madspin.py (+546/-128)
Template/Common/Cards/madspin_card_default.dat (+6/-2)
Template/LO/Cards/pythia8_card_default.dat (+7/-1)
Template/LO/SubProcesses/makefile (+2/-2)
Template/LO/SubProcesses/myamp.f (+0/-3)
Template/LO/bin/internal/gen_jpeg-pl (+2/-2)
Template/NLO/Cards/FO_analyse_card.dat (+3/-1)
Template/NLO/FixedOrderAnalysis/HwU.f (+52/-8)
Template/NLO/FixedOrderAnalysis/analysis_HwU_pp_lplm.f (+44/-44)
Template/NLO/MCatNLO/HWAnalyzer/hw6an_HwU_pp_V.f (+1/-1)
Template/NLO/MCatNLO/shower_template.sh (+1/-1)
Template/NLO/MCatNLO/srcHerwig/madfks_hwlhin.f (+0/-1)
Template/NLO/Source/ranmar.f (+4/-3)
Template/NLO/Source/run.inc (+5/-1)
Template/NLO/SubProcesses/HwU_dummy.f (+2/-1)
Template/NLO/SubProcesses/ajob_template (+5/-1)
Template/NLO/SubProcesses/analysis_lhe.f (+222/-0)
Template/NLO/SubProcesses/driver_mintFO.f (+93/-76)
Template/NLO/SubProcesses/driver_mintMC.f (+70/-78)
Template/NLO/SubProcesses/fks_singular.f (+33/-17)
Template/NLO/SubProcesses/madfks_plot.f (+3/-8)
Template/NLO/SubProcesses/mint-integrator2.f (+461/-231)
Template/NLO/SubProcesses/mint.inc (+16/-0)
Template/NLO/SubProcesses/montecarlocounter.f (+35/-3)
Template/NLO/SubProcesses/setcuts.f (+124/-123)
Template/NLO/SubProcesses/symmetry_fks_test_MC.f (+5/-2)
Template/NLO/SubProcesses/symmetry_fks_test_ME.f (+5/-2)
Template/NLO/SubProcesses/symmetry_fks_v3.f (+4/-1)
Template/NLO/SubProcesses/write_event.f (+2/-4)
Template/loop_material/StandAlone/SubProcesses/makefile (+2/-0)
UpdateNotes.txt (+20/-0)
aloha/aloha_lib.py (+7/-2)
aloha/aloha_parsers.py (+5/-1)
aloha/create_aloha.py (+4/-3)
bin/compile.py (+55/-21)
bin/create_release.py (+5/-1)
bin/mg5_aMC (+8/-1)
madgraph/core/base_objects.py (+4/-0)
madgraph/core/diagram_generation.py (+11/-7)
madgraph/core/helas_objects.py (+65/-5)
madgraph/interface/amcatnlo_run_interface.py (+419/-75)
madgraph/interface/common_run_interface.py (+62/-32)
madgraph/interface/extended_cmd.py (+6/-4)
madgraph/interface/launch_ext_program.py (+8/-14)
madgraph/interface/madevent_interface.py (+157/-88)
madgraph/interface/madgraph_interface.py (+24/-12)
madgraph/interface/reweight_interface.py (+23/-14)
madgraph/iolibs/export_fks.py (+6/-6)
madgraph/iolibs/export_v4.py (+28/-5)
madgraph/loop/loop_color_amp.py (+1/-1)
madgraph/loop/loop_exporters.py (+9/-4)
madgraph/loop/loop_helas_objects.py (+12/-7)
madgraph/madevent/gen_ximprove.py (+1/-1)
madgraph/madevent/sum_html.py (+10/-6)
madgraph/various/FO_analyse_card.py (+18/-6)
madgraph/various/banner.py (+22/-7)
madgraph/various/histograms.py (+1/-1)
madgraph/various/lhe_parser.py (+183/-35)
madgraph/various/misc.py (+64/-16)
madgraph/various/systematics.py (+5/-0)
mg5decay/decay_objects.py (+20/-3)
models/__init__.py (+1/-0)
models/check_param_card.py (+14/-5)
models/import_ufo.py (+4/-8)
models/usermod.py (+27/-12)
models/write_param_card.py (+6/-0)
tests/acceptance_tests/test_cmd_amcatnlo.py (+1/-1)
tests/acceptance_tests/test_cmd_madevent.py (+4/-1)
tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_dxu_wp%V0_dxu_wp%global_specs.inc (+6/-0)
tests/input_files/IOTestsComparison/IOExportFKSTest/test_ppw_fksall/%SubProcesses%P0_udx_wp%V0_udx_wp%global_specs.inc (+6/-0)
tests/input_files/run_card_matching.dat (+1/-0)
tests/parallel_tests/test_aloha.py (+105/-0)
tests/test_manager.py (+44/-14)
tests/unit_tests/interface/test_edit_card.py (+6/-3)
tests/unit_tests/iolibs/test_export_cpp.py (+1/-0)
tests/unit_tests/various/test_banner.py (+30/-7)
tests/unit_tests/various/test_process_checks.py (+2/-2)
tests/unit_tests/various/test_usermod.py (+29/-10)
vendor/IREGI/src/oneloop/create.py (+2/-2)
To merge this branch: bzr merge lp:~olivier-mattelaer/mg5amcnlo/2.5.3
Reviewer Review Type Date Requested Status
Rikkert Frederix Approve
Olivier Mattelaer Approve
Review via email: mp+318969@code.launchpad.net

Description of the change

Hi,

Any objection for releasing 2.5.3?

Cheers,

Olivier

To post a comment you must log in.
302. By olivier-mattelaer

fixing one small bug

303. By olivier-mattelaer

fixing a tricky error related to multi_run with pgs

304. By olivier-mattelaer

ensure that the group number is correctly propagated even on distributted system

305. By Valentin Hirschi

1. Fixed an issues found by Huasheng on the computation of the loop symmetry factor in very special cases.

306. By Hua-Sheng Shao

1) add suffice for avh_olo.f90 and avh_olo.o in create.py of IREGI/src/oneloop; 2) Correct one lhaid of PDF4LHC15 in histograms.py

307. By Valentin Hirschi

1. Enforced sequential build of CutTools in our compilation steered by MG5aMC.
   Nowadays almost all version of make support the '-j' options and an increasing
   number of environment are now automatically turning on parallel build, so this must
   be done.
   Ideally one would either fix CutTools target dependencies to support paralell build
   or enforce sequential build directly in its makefile, but unfortunately none of these
   two options are easy to implement.

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

Hi,

I guess this means that everyone approves. So I freeze the version here.
If you want to have something in 2.5.3. Please contact me since apriori any version after this one will not be part of 2.5.3 release. (I might still make one or two push depending if some of the tests fails or not)

Cheers,

Olivier

review: Approve
308. By Rikkert Frederix

small improvement in the length of the buffer. Needed for processes
with more than 100 integration channels at the Born level.

Revision history for this message
Rikkert Frederix (frederix) wrote :

Hi Olivier,

Just submitted and pushed a final improvement. So, now it's good to go.

Cheers,
Rik

review: Approve

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 2016-12-09 00:39:21 +0000
3+++ MadSpin/decay.py 2017-03-08 10:27:27 +0000
4@@ -1919,7 +1919,6 @@
5 sd=sd/(N-1.0)
6
7 return mean, sd
8-
9
10 class decay_all_events(object):
11
12@@ -2026,7 +2025,6 @@
13 self.all_decay = {}
14
15
16-
17 # generate BR and all the square matrix element based on the banner.
18 pickle_info = pjoin(self.path_me,"production_me", "all_ME.pkl")
19 if not options["use_old_dir"] or not os.path.exists(pickle_info):
20@@ -2042,7 +2040,7 @@
21 save_load_object.save_to_file(pickle_info,
22 (self.all_ME,self.all_decay,self.width_estimator))
23
24- if not self.options["onlyhelicity"]:
25+ if not self.options["onlyhelicity"] and self.options['spinmode'] != 'onshell':
26 resonances = self.width_estimator.resonances
27 logger.debug('List of resonances: %s' % resonances)
28 self.extract_resonances_mass_width(resonances)
29@@ -2669,9 +2667,8 @@
30 #self.banner.get('proc_card').get('multiparticles'):
31 mgcmd.do_define("%s = %s" % (name, ' '.join(`i` for i in pdgs)))
32
33-
34+
35 mgcmd.exec_cmd("set group_subprocesses False")
36-
37 logger.info('generating the production square matrix element')
38 start = time.time()
39 commandline=''
40@@ -2762,7 +2759,7 @@
41
42 # 4. compute the full matrix element -----------------------------------
43 if not self.options["onlyhelicity"]:
44- logger.info('generating the full square matrix element (with decay)')
45+ logger.info('generating the full matrix element squared (with decay)')
46 start = time.time()
47 to_decay = self.mscmd.list_branches.keys()
48 decay_text = []
49@@ -4009,3 +4006,283 @@
50 del external
51
52 self.calculator = {}
53+
54+
55+
56+
57+class decay_all_events_onshell(decay_all_events):
58+ """special mode for onshell production"""
59+
60+ @misc.mute_logger()
61+ @misc.set_global()
62+ def generate_all_matrix_element(self):
63+ """generate the full series of matrix element needed by Madspin.
64+ i.e. the undecayed and the decay one. And associate those to the
65+ madspin production_topo object"""
66+
67+ # 1. compute the partial width
68+ # 2. compute the production matrix element
69+ # 3. create the all_topology object
70+ # 4. compute the full matrix element (use the partial to throw away
71+ # pointless decay.
72+ # 5. add the decay information to the all_topology object (with branching
73+ # ratio)
74+
75+
76+ # 0. clean previous run ------------------------------------------------
77+ path_me = self.path_me
78+ try:
79+ shutil.rmtree(pjoin(path_me,'madspin_me'))
80+ except Exception:
81+ pass
82+
83+ # 1. compute the partial width------------------------------------------
84+ #self.get_branching_ratio()
85+
86+ # 2. compute the production matrix element -----------------------------
87+ processes = [line[9:].strip() for line in self.banner.proc_card
88+ if line.startswith('generate')]
89+ processes += [' '.join(line.split()[2:]) for line in self.banner.proc_card
90+ if re.search('^\s*add\s+process', line)]
91+
92+ mgcmd = self.mgcmd
93+ modelpath = self.model.get('modelpath+restriction')
94+
95+ commandline="import model %s" % modelpath
96+ if not self.model.mg5_name:
97+ commandline += ' --modelname'
98+
99+ mgcmd.exec_cmd(commandline)
100+ # Handle the multiparticle of the banner
101+ #for name, definition in self.mscmd.multiparticles:
102+ if hasattr(self.mscmd, 'multiparticles_ms'):
103+ for name, pdgs in self.mscmd.multiparticles_ms.items():
104+ if name == 'all':
105+ continue
106+ #self.banner.get('proc_card').get('multiparticles'):
107+ mgcmd.do_define("%s = %s" % (name, ' '.join(`i` for i in pdgs)))
108+
109+
110+ mgcmd.exec_cmd("set group_subprocesses False")
111+ logger.info('generating the production square matrix element')
112+ start = time.time()
113+ commandline=''
114+ for proc in processes:
115+ # deal with @ syntax need to move it after the decay specification
116+ if '@' in proc:
117+ proc, proc_nb = proc.split('@')
118+ try:
119+ proc_nb = int(proc_nb)
120+ except ValueError:
121+ raise MadSpinError, 'MadSpin didn\'t allow order restriction after the @ comment: \"%s\" not valid' % proc_nb
122+ proc_nb = '@ %i' % proc_nb
123+ else:
124+ proc_nb = ''
125+
126+ if ',' in proc:
127+ raise MadSpinError, 'MadSpin can not decay event which comes from a decay chain.'+\
128+ '\n The full decay chain should either be handle by MadGraph or by Masdspin.'
129+
130+ if '[' not in proc:
131+ commandline+="add process %s %s --no_warning=duplicate;" % (proc, proc_nb)
132+ else:
133+ process, order, final = re.split('\[\s*(.*)\s*\]', proc)
134+ commandline+="add process %s %s --no_warning=duplicate;" % (process, proc_nb)
135+ if not order:
136+ continue
137+ elif not order.startswith('virt='):
138+ if '=' in order:
139+ order = order.split('=',1)[1]
140+ # define the list of particles that are needed for the radiateion
141+ pert = fks_common.find_pert_particles_interactions(
142+ mgcmd._curr_model,pert_order = order)['soft_particles']
143+ commandline += "define pert_%s = %s;" % (order, ' '.join(map(str,pert)) )
144+
145+ # check if we have to increase by one the born order
146+ if '%s=' % order in process:
147+ result=re.split(' ',process)
148+ process=''
149+ for r in result:
150+ if '%s=' % order in r:
151+ ior=re.split('=',r)
152+ r='QCD=%i' % (int(ior[1])+1)
153+ process=process+r+' '
154+ #handle special tag $ | / @
155+ result = re.split('([/$@]|\w+=\w+)', process, 1)
156+ if len(result) ==3:
157+ process, split, rest = result
158+ commandline+="add process %s pert_%s %s%s %s --no_warning=duplicate;" % (process, order ,split, rest, proc_nb)
159+ else:
160+ commandline +='add process %s pert_%s %s --no_warning=duplicate;' % (process,order, proc_nb)
161+# commandline = commandline.replace('add process', 'generate',1)
162+# logger.info(commandline)
163+#
164+# mgcmd.exec_cmd(commandline, precmd=True)
165+# commandline = 'output standalone_msP %s %s' % \
166+# (pjoin(path_me,'production_me'), ' '.join(self.list_branches.keys()))
167+# mgcmd.exec_cmd(commandline, precmd=True)
168+# logger.info('Done %.4g' % (time.time()-start))
169+
170+ # 3. Create all_ME + topology objects ----------------------------------
171+# matrix_elements = mgcmd._curr_matrix_elements.get_matrix_elements()
172+# self.all_ME.adding_me(matrix_elements, pjoin(path_me,'production_me'))
173+
174+ # 4. compute the full matrix element -----------------------------------
175+ logger.info('generating the full matrix element squared (with decay)')
176+# start = time.time()
177+ to_decay = self.mscmd.list_branches.keys()
178+ decay_text = []
179+ for decays in self.mscmd.list_branches.values():
180+ for decay in decays:
181+ if '=' not in decay:
182+ decay += ' QCD=99'
183+ if ',' in decay:
184+ decay_text.append('(%s)' % decay)
185+ else:
186+ decay_text.append(decay)
187+ decay_text = ', '.join(decay_text)
188+# commandline = ''
189+
190+
191+ for proc in processes:
192+ # deal with @ syntax need to move it after the decay specification
193+ if '@' in proc:
194+ proc, proc_nb = proc.split('@')
195+ try:
196+ proc_nb = int(proc_nb)
197+ except ValueError:
198+ raise MadSpinError, 'MadSpin didn\'t allow order restriction after the @ comment: \"%s\" not valid' % proc_nb
199+ proc_nb = '@ %i' % proc_nb
200+ else:
201+ proc_nb = ''
202+
203+ if '[' not in proc:
204+ nb_comma = proc.count(',')
205+ if nb_comma == 0:
206+ commandline+="add process %s, %s %s --no_warning=duplicate;" % (proc, decay_text, proc_nb)
207+ elif nb_comma == 1:
208+ before, after = proc.split(',')
209+ commandline+="add process %s, %s, (%s, %s) %s --no_warning=duplicate;" % (before, decay_text, after, decay_text, proc_nb)
210+ else:
211+ raise Exception, 'too much decay at MG level. this can not be done for the moment)'
212+ else:
213+ process, order, final = re.split('\[\s*(.*)\s*\]', proc)
214+ commandline+="add process %s, %s %s --no_warning=duplicate;" % (process, decay_text, proc_nb)
215+ if not order:
216+ continue
217+ elif not order.startswith('virt='):
218+ if '=' in order:
219+ order = order.split('=',1)[1]
220+ # define the list of particles that are needed for the radiateion
221+ pert = fks_common.find_pert_particles_interactions(
222+ mgcmd._curr_model,pert_order = order)['soft_particles']
223+ commandline += "define pert_%s = %s;" % (order, ' '.join(map(str,pert)) )
224+
225+ # check if we have to increase by one the born order
226+ if '%s=' % order in process:
227+ result=re.split(' ',process)
228+ process=''
229+ for r in result:
230+ if '%s=' % order in r:
231+ ior=re.split('=',r)
232+ r='QCD=%i' % (int(ior[1])+1)
233+ process=process+r+' '
234+ #handle special tag $ | / @
235+ result = re.split('([/$@]|\w+=\w+)', process, 1)
236+ if len(result) ==3:
237+ process, split, rest = result
238+ commandline+="add process %s pert_%s %s%s , %s %s --no_warning=duplicate;" % \
239+ (process, order, split, rest, decay_text, proc_nb)
240+ else:
241+ commandline +='add process %s pert_%s, %s %s --no_warning=duplicate;' % \
242+ (process, order, decay_text, proc_nb)
243+# commandline = commandline.replace('add process', 'generate',1)
244+# logger.info(commandline)
245+# mgcmd.exec_cmd(commandline, precmd=True)
246+ # remove decay with 0 branching ratio.
247+# mgcmd.remove_pointless_decay(self.banner.param_card)
248+# commandline = 'output standalone_msF %s %s' % (pjoin(path_me,'full_me'),
249+# ' '.join(self.list_branches.keys()))
250+# mgcmd.exec_cmd(commandline, precmd=True)
251+# logger.info('Done %.4g' % (time.time()-start))
252+
253+
254+
255+
256+ # 5. add the decay information to the all_topology object --------------
257+# for matrix_element in mgcmd._curr_matrix_elements.get_matrix_elements():
258+# me_path = pjoin(path_me,'full_me', 'SubProcesses', \
259+# "P%s" % matrix_element.get('processes')[0].shell_string())
260+# self.all_ME.add_decay(matrix_element, me_path)
261+
262+ # 5.b import production matrix elements (+ related info) in the full process directory
263+# list_prodfiles=['matrix_prod.f','configs_production.inc','props_production.inc','nexternal_prod.inc']
264+# for tag in self.all_ME:
265+# prod_path=self.all_ME[tag]['path']
266+# nfinal=len(self.all_ME[tag]['base_order'][1])
267+# for dico in self.all_ME[tag]['decays']:
268+# full_path=dico['path']
269+ #print prod_path
270+ #print full_path
271+ #print ' '
272+# for item in list_prodfiles:
273+ #print full_path
274+# prodfile=pjoin(prod_path,item)
275+# destination=pjoin(full_path,item)
276+# shutil.copyfile(prodfile, destination)
277+ # we need to write the file config_decays.inc
278+# self.generate_configs_file(nfinal,dico,full_path)
279+
280+
281+# if self.options["onlyhelicity"]:
282+# return
283+
284+ # 6. generate decay only part ------------------------------------------
285+ logger.info('generate matrix element for decay only (1 - > N).')
286+# start = time.time()
287+# commandline = ''
288+ i=0
289+ for processes in self.list_branches.values():
290+ for proc in processes:
291+ commandline+="add process %s @%i --no_warning=duplicate --standalone;" % (proc,i)
292+ i+=1
293+ commandline = commandline.replace('add process', 'generate',1)
294+ mgcmd.exec_cmd(commandline, precmd=True)
295+ # remove decay with 0 branching ratio.
296+ #mgcmd.remove_pointless_decay(self.banner.param_card)
297+ #
298+ commandline = 'output standalone %s' % pjoin(path_me,'madspin_me')
299+ logger.info(commandline)
300+ mgcmd.exec_cmd(commandline, precmd=True)
301+ logger.info('Done %.4g' % (time.time()-start))
302+ self.all_me = {}
303+
304+ # store information about matrix element
305+ for matrix_element in mgcmd._curr_matrix_elements.get_matrix_elements():
306+ me_string = matrix_element.get('processes')[0].shell_string()
307+ for me in matrix_element.get('processes'):
308+ dirpath = pjoin(path_me,'madspin_me', 'SubProcesses', "P%s" % me_string)
309+ # get the orignal order:
310+ initial = []
311+ final = [l.get('id') for l in me.get_legs_with_decays()\
312+ if l.get('state') or initial.append(l.get('id'))]
313+ order = (tuple(initial), tuple(final))
314+ initial.sort(), final.sort()
315+ tag = (tuple(initial), tuple(final))
316+ self.all_me[tag] = {'pdir': "P%s" % me_string, 'order': order}
317+
318+
319+ return self.all_me
320+
321+
322+
323+ def compile(self):
324+ logger.info('Compiling code')
325+ misc.compile(cwd=pjoin(self.path_me,'madspin_me', 'Source'),
326+ nb_core=self.mgcmd.options['nb_core'])
327+ misc.compile(['all'],cwd=pjoin(self.path_me,'madspin_me', 'SubProcesses'),
328+ nb_core=self.mgcmd.options['nb_core'])
329+
330+
331+
332+
333
334=== modified file 'MadSpin/interface_madspin.py'
335--- MadSpin/interface_madspin.py 2016-11-25 15:38:07 +0000
336+++ MadSpin/interface_madspin.py 2017-03-08 10:27:27 +0000
337@@ -21,6 +21,8 @@
338 import random
339 import re
340 import shutil
341+import sys
342+import time
343 import glob
344
345
346@@ -33,6 +35,7 @@
347 import madgraph.interface.madgraph_interface as mg_interface
348 import madgraph.interface.master_interface as master_interface
349 import madgraph.interface.madevent_interface as madevent_interface
350+import madgraph.interface.reweight_interface as rwgt_interface
351 import madgraph.various.misc as misc
352 import madgraph.iolibs.files as files
353 import madgraph.iolibs.export_v4 as export_v4
354@@ -44,6 +47,7 @@
355 import MadSpin.decay as madspin
356
357
358+
359 logger = logging.getLogger('decay.stdout') # -> stdout
360 logger_stderr = logging.getLogger('decay.stderr') # ->stderr
361 cmd_logger = logging.getLogger('cmdprint2') # -> print
362@@ -128,7 +132,7 @@
363 inputfile = inputfile + '.gz'
364 else:
365 raise self.InvalidCmd('No such file or directory : %s' % inputfile)
366-
367+
368 if inputfile.endswith('.gz'):
369 misc.gunzip(inputfile)
370 inputfile = inputfile[:-3]
371@@ -371,8 +375,8 @@
372 raise self.InvalidCmd('second argument should be a path to a existing directory')
373
374 elif args[0] == "spinmode":
375- if args[1].lower() not in ["full", "bridge", "none"]:
376- raise self.InvalidCmd("spinmode can only take one of those 3 value: full/bridge/none")
377+ if args[1].lower() not in ["full", "onshell", "none"]:
378+ raise self.InvalidCmd("spinmode can only take one of those 3 value: full/onshell/none")
379
380 elif args[0] == "run_card":
381 if self.options['spinmode'] == "madspin":
382@@ -438,7 +442,7 @@
383 if a.endswith(os.path.sep)])
384 return self.path_completion(text, curr_path, only_dirs = True)
385 elif args[1] == "spinmode":
386- return self.list_completion(text, ["full", "none"], line)
387+ return self.list_completion(text, ["full","onshell", "none"], line)
388
389 def help_set(self):
390 """help the set command"""
391@@ -516,14 +520,16 @@
392 launch
393 '''
394
395- #@misc.mute_logger()
396+ @misc.mute_logger()
397 def do_launch(self, line):
398 """end of the configuration launched the code"""
399
400 if self.options["spinmode"] in ["none"]:
401 return self.run_bridge(line)
402+ elif self.options["spinmode"] == "onshell":
403+ return self.run_onshell(line)
404 elif self.options["spinmode"] == "bridge":
405- raise Exception, "Bridge mode not yet available due to lack of validation."
406+ raise Exception, "Bridge mode not available."
407
408 if self.options['ms_dir'] and os.path.exists(pjoin(self.options['ms_dir'], 'madspin.pkl')):
409 return self.run_from_pickle()
410@@ -693,6 +699,8 @@
411 if not self.mother:
412 logger.info("Decayed events have been written in %s.gz" % decayed_evt_file)
413
414+
415+
416 def run_bridge(self, line):
417 """Run the Bridge Algorithm"""
418
419@@ -700,111 +708,7 @@
420 # of event to generate for each type of particle.
421 # 2. Generate the events requested
422 # 3. perform the merge of the events.
423- # if not enough events. re-generate the missing one.
424- # First define an utility function for generating events when needed
425- def generate_events(pdg, nb_event, mg5, restrict_file=None, cumul=False):
426- """generate new events for this particle
427- restrict_file allow to only generate a subset of the definition
428- cumul allow to merge all the definition in one run (add process)
429- to generate events according to cross-section
430- """
431-
432- part = self.model.get_particle(pdg)
433- if not part:
434- return {}# this particle is not defined in the current model so ignore it
435- name = part.get_name()
436- out = {}
437- logger.info("generate %s decay event for particle %s" % (nb_event, name))
438- if name not in self.list_branches:
439- return out
440- for i,proc in enumerate(self.list_branches[name]):
441- if restrict_file and i not in restrict_file:
442- continue
443- decay_dir = pjoin(self.path_me, "decay_%s_%s" %(str(pdg).replace("-","x"),i))
444- if not os.path.exists(decay_dir):
445- if cumul:
446- mg5.exec_cmd("generate %s" % proc)
447- for j,proc2 in enumerate(self.list_branches[name][1:]):
448- if restrict_file and j not in restrict_file:
449- raise Exception # Do not see how this can happen
450- mg5.exec_cmd("add process %s" % proc2)
451- mg5.exec_cmd("output %s -f" % decay_dir)
452- else:
453- mg5.exec_cmd("generate %s" % proc)
454- mg5.exec_cmd("output %s -f" % decay_dir)
455-
456- options = dict(mg5.options)
457- if self.options['ms_dir']:
458- misc.sprint("start gridpack!")
459- # we are in gridpack mode -> create it
460- me5_cmd = madevent_interface.MadEventCmdShell(me_dir=os.path.realpath(\
461- decay_dir), options=options)
462- me5_cmd.options["automatic_html_opening"] = False
463- me5_cmd.options["madanalysis5_path"] = None
464- me5_cmd.options["madanalysis_path"] = None
465- try:
466- os.remove(pjoin(decay_dir, 'Cards', 'madanalysis5_parton_card_default.dat'))
467- os.remove(pjoin(decay_dir, 'Cards', 'madanalysis5_parton_card.dat'))
468- except Exception,error:
469- logger.debug(error)
470- pass
471- misc.sprint(os.listdir(pjoin(decay_dir,'Cards')))
472- if self.options["run_card"]:
473- run_card = self.options["run_card"]
474- else:
475- run_card = banner.RunCard(pjoin(decay_dir, "Cards", "run_card.dat"))
476-
477- run_card["iseed"] = self.seed
478- run_card['gridpack'] = True
479- run_card['systematics_program'] = False
480- run_card.write(pjoin(decay_dir, "Cards", "run_card.dat"))
481- param_card = self.banner['slha']
482- open(pjoin(decay_dir, "Cards", "param_card.dat"),"w").write(param_card)
483- self.seed += 1
484- # actually creation
485- me5_cmd.exec_cmd("generate_events run_01 -f")
486- me5_cmd.exec_cmd("exit")
487- #remove pointless informat
488- misc.call(["rm", "Cards", "bin", 'Source', 'SubProcesses'], cwd=decay_dir)
489- misc.call(['tar', '-xzpvf', 'run_01_gridpack.tar.gz'], cwd=decay_dir)
490-
491- # Now generate the events
492-
493- if not self.options['ms_dir']:
494- me5_cmd = madevent_interface.MadEventCmdShell(me_dir=os.path.realpath(\
495- decay_dir), options=mg5.options)
496- me5_cmd.options["automatic_html_opening"] = False
497- me5_cmd.options["madanalysis5_path"] = None
498- me5_cmd.options["madanalysis_path"] = None
499- try:
500- os.remove(pjoin(decay_dir, 'Cards', 'madanalysis5_parton_card_default.dat'))
501- os.remove(pjoin(decay_dir, 'Cards', 'madanalysis5_parton_card.dat'))
502- except Exception,error:
503- logger.debug(error)
504- pass
505-
506- if self.options["run_card"]:
507- run_card = self.options["run_card"]
508- else:
509- run_card = banner.RunCard(pjoin(decay_dir, "Cards", "run_card.dat"))
510- run_card["nevents"] = int(1.2*nb_event)
511- run_card["iseed"] = self.seed
512- run_card["systematics_program"] = 'None'
513- run_card.write(pjoin(decay_dir, "Cards", "run_card.dat"))
514- param_card = self.banner['slha']
515- open(pjoin(decay_dir, "Cards", "param_card.dat"),"w").write(param_card)
516- self.seed += 1
517- me5_cmd.exec_cmd("generate_events run_01 -f")
518- me5_cmd.exec_cmd("exit")
519- out[i] = lhe_parser.EventFile(pjoin(decay_dir, "Events", 'run_01', 'unweighted_events.lhe.gz'))
520- else:
521- misc.call(['run.sh', str(int(1.2*nb_event)), str(self.seed)], cwd=decay_dir)
522- out[i] = lhe_parser.EventFile(pjoin(decay_dir, 'events.lhe.gz'))
523- if cumul:
524- break
525-
526- return out
527-
528+ # if not enough events. re-generate the missing one.
529
530 args = self.split_arg(line)
531
532@@ -854,11 +758,11 @@
533 if not self.model:
534 modelpath = self.model.get('modelpath+restriction')
535 mg5.exec_cmd("import model %s" % modelpath)
536- to_event = {}
537+ evt_decayfile = {}
538 for pdg, nb_needed in to_decay.items():
539 #check if a splitting is needed
540 if nb_needed == nb_event:
541- to_event[pdg] = generate_events(pdg, nb_needed, mg5)
542+ evt_decayfile[pdg] = self.generate_events(pdg, nb_needed, mg5)
543 elif nb_needed % nb_event == 0:
544 nb_mult = nb_needed // nb_event
545 part = self.model.get_particle(pdg)
546@@ -866,9 +770,9 @@
547 if name not in self.list_branches:
548 continue
549 elif len(self.list_branches[name]) == nb_mult:
550- to_event[pdg] = generate_events(pdg, nb_event, mg5)
551+ evt_decayfile[pdg] = self.generate_events(pdg, nb_event, mg5)
552 else:
553- to_event[pdg] = generate_events(pdg, nb_needed, mg5, cumul=True)
554+ evt_decayfile[pdg] = self.generate_events(pdg, nb_needed, mg5, cumul=True)
555 else:
556 part = self.model.get_particle(pdg)
557 name = part.get_name()
558@@ -881,7 +785,7 @@
559
560 # Compute the branching ratio.
561 br = 1
562- for (pdg, event_files) in to_event.items():
563+ for (pdg, event_files) in evt_decayfile.items():
564 if not event_files:
565 continue
566 totwidth = float(self.banner.get('param', 'decay', abs(pdg)).value)
567@@ -927,8 +831,8 @@
568
569 # initialise object which store not use event due to wrong helicity
570 bufferedEvents_decay = {}
571- for pdg in to_event:
572- bufferedEvents_decay[pdg] = [{}] * len(to_event[pdg])
573+ for pdg in evt_decayfile:
574+ bufferedEvents_decay[pdg] = [{}] * len(evt_decayfile[pdg])
575
576 import time
577 start = time.time()
578@@ -946,25 +850,25 @@
579 ids = [particle.pid for particle in particles]
580 for i,particle in enumerate(particles):
581 # check if we need to decay the particle
582- if particle.pdg not in self.final_state or particle.pdg not in to_event:
583+ if particle.pdg not in self.final_state or particle.pdg not in evt_decayfile:
584 continue # nothing to do for this particle
585 # check how the decay need to be done
586- nb_decay = len(to_event[particle.pdg])
587+ nb_decay = len(evt_decayfile[particle.pdg])
588 if nb_decay == 0:
589 continue #nothing to do for this particle
590 if nb_decay == 1:
591- decay_file = to_event[particle.pdg][0]
592+ decay_file = evt_decayfile[particle.pdg][0]
593 decay_file_nb = 0
594 elif ids.count(particle.pdg) == nb_decay:
595- decay_file = to_event[particle.pdg][ids[:i].count(particle.pdg)]
596+ decay_file = evt_decayfile[particle.pdg][ids[:i].count(particle.pdg)]
597 decay_file_nb = ids[:i].count(particle.pdg)
598 else:
599 #need to select the file according to the associate cross-section
600 r = random.random()
601- tot = sum(to_event[particle.pdg][key].cross for key in to_event[particle.pdg])
602+ tot = sum(evt_decayfile[particle.pdg][key].cross for key in evt_decayfile[particle.pdg])
603 r = r * tot
604 cumul = 0
605- for j,events in to_event[particle.pdg].items():
606+ for j,events in evt_decayfile[particle.pdg].items():
607 cumul += events.cross
608 if r < cumul:
609 decay_file = events
610@@ -991,9 +895,9 @@
611 needed = 1.05 * to_decay[particle.pdg]/ratio - counter
612 needed = min(1000, max(needed, 1000))
613 with misc.MuteLogger(["madgraph", "madevent", "ALOHA", "cmdprint"], [50,50,50,50]):
614- new_file = generate_events(particle.pdg, needed, mg5, [decay_file_nb])
615- to_event[particle.pdg].update(new_file)
616- decay_file = to_event[particle.pdg][decay_file_nb]
617+ new_file = self.generate_events(particle.pdg, needed, mg5, [decay_file_nb])
618+ evt_decayfile[particle.pdg].update(new_file)
619+ decay_file = evt_decayfile[particle.pdg][decay_file_nb]
620 continue
621 if helicity == decay[0].helicity or helicity==9 or \
622 self.options["spinmode"] == "none":
623@@ -1013,7 +917,7 @@
624 wgts[key] *= self.branching_ratio
625 # all particle have been decay if needed
626 output_lhe.write(str(event))
627- output_lhe.write('</LesHouchesEvent>\n')
628+ output_lhe.write('</LesHouchesEvents>\n')
629
630
631 def load_model(self, name, use_mg_default, complex_mass=False):
632@@ -1042,6 +946,520 @@
633 self.mg5cmd._curr_model = self.model
634 self.mg5cmd.process_model()
635
636+ def generate_events(self, pdg, nb_event, mg5, restrict_file=None, cumul=False,
637+ output_width=False):
638+ """generate new events for this particle
639+ restrict_file allow to only generate a subset of the definition
640+ cumul allow to merge all the definition in one run (add process)
641+ to generate events according to cross-section
642+ """
643+
644+ if cumul:
645+ width = 0.
646+ else:
647+ width = 1.
648+ part = self.model.get_particle(pdg)
649+ if not part:
650+ return {}# this particle is not defined in the current model so ignore it
651+ name = part.get_name()
652+ out = {}
653+ logger.info("generate %s decay event for particle %s" % (int(nb_event), name))
654+ if name not in self.list_branches:
655+ return out
656+ for i,proc in enumerate(self.list_branches[name]):
657+ if restrict_file and i not in restrict_file:
658+ continue
659+ decay_dir = pjoin(self.path_me, "decay_%s_%s" %(str(pdg).replace("-","x"),i))
660+ if not os.path.exists(decay_dir):
661+ if cumul:
662+ mg5.exec_cmd("generate %s" % proc)
663+ for j,proc2 in enumerate(self.list_branches[name][1:]):
664+ if restrict_file and j not in restrict_file:
665+ raise Exception # Do not see how this can happen
666+ mg5.exec_cmd("add process %s" % proc2)
667+ mg5.exec_cmd("output %s -f" % decay_dir)
668+ else:
669+ mg5.exec_cmd("generate %s" % proc)
670+ mg5.exec_cmd("output %s -f" % decay_dir)
671+
672+ options = dict(mg5.options)
673+ if self.options['ms_dir']:
674+ # we are in gridpack mode -> create it
675+ me5_cmd = madevent_interface.MadEventCmdShell(me_dir=os.path.realpath(\
676+ decay_dir), options=options)
677+ me5_cmd.options["automatic_html_opening"] = False
678+ me5_cmd.options["madanalysis5_path"] = None
679+ me5_cmd.options["madanalysis_path"] = None
680+ me5_cmd.allow_notification_center = False
681+ try:
682+ os.remove(pjoin(decay_dir, 'Cards', 'madanalysis5_parton_card_default.dat'))
683+ os.remove(pjoin(decay_dir, 'Cards', 'madanalysis5_parton_card.dat'))
684+ except Exception,error:
685+ logger.debug(error)
686+ pass
687+ if self.options["run_card"]:
688+ run_card = self.options["run_card"]
689+ else:
690+ run_card = banner.RunCard(pjoin(decay_dir, "Cards", "run_card.dat"))
691+
692+ run_card["iseed"] = self.seed
693+ run_card['gridpack'] = True
694+ run_card['systematics_program'] = False
695+ run_card.write(pjoin(decay_dir, "Cards", "run_card.dat"))
696+ param_card = self.banner['slha']
697+ open(pjoin(decay_dir, "Cards", "param_card.dat"),"w").write(param_card)
698+ self.seed += 1
699+ # actually creation
700+ me5_cmd.exec_cmd("generate_events run_01 -f")
701+ if output_width:
702+ if cumul:
703+ width += me5_cmd.results.current['cross']
704+ else:
705+ width *= me5_cmd.results.current['cross']
706+ me5_cmd.exec_cmd("exit")
707+ #remove pointless informat
708+ misc.call(["rm", "Cards", "bin", 'Source', 'SubProcesses'], cwd=decay_dir)
709+ misc.call(['tar', '-xzpvf', 'run_01_gridpack.tar.gz'], cwd=decay_dir)
710+
711+ # Now generate the events
712+
713+ if not self.options['ms_dir']:
714+ me5_cmd = madevent_interface.MadEventCmdShell(me_dir=os.path.realpath(\
715+ decay_dir), options=mg5.options)
716+ me5_cmd.options["automatic_html_opening"] = False
717+ me5_cmd.options["automatic_html_opening"] = False
718+ me5_cmd.options["madanalysis5_path"] = None
719+ me5_cmd.options["madanalysis_path"] = None
720+ me5_cmd.allow_notification_center = False
721+ try:
722+ os.remove(pjoin(decay_dir, 'Cards', 'madanalysis5_parton_card_default.dat'))
723+ os.remove(pjoin(decay_dir, 'Cards', 'madanalysis5_parton_card.dat'))
724+ except Exception,error:
725+ logger.debug(error)
726+ pass
727+ if self.options["run_card"]:
728+ run_card = self.options["run_card"]
729+ else:
730+ run_card = banner.RunCard(pjoin(decay_dir, "Cards", "run_card.dat"))
731+ run_card["nevents"] = int(1.2*nb_event)
732+ run_card["iseed"] = self.seed
733+ run_card["systematics_program"] = 'None'
734+ run_card.write(pjoin(decay_dir, "Cards", "run_card.dat"))
735+ param_card = self.banner['slha']
736+ open(pjoin(decay_dir, "Cards", "param_card.dat"),"w").write(param_card)
737+ self.seed += 1
738+ me5_cmd.exec_cmd("generate_events run_01 -f")
739+ if output_width:
740+ if cumul:
741+ width += me5_cmd.results.current['cross']
742+ else:
743+ width *= me5_cmd.results.current['cross']
744+ if run_card["nevents"] > 1.01 * me5_cmd.results.current['nb_event']:
745+ logger.critical('The number of event generated is only %s/%s. This typically indicates that you need specify cut on the decay process.',me5_cmd.results.current['nb_event'], run_card["nevents"])
746+ logger.critical('We strongly suggest that you cancel/discard this run.')
747+ me5_cmd.exec_cmd("exit")
748+ out[i] = lhe_parser.EventFile(pjoin(decay_dir, "Events", 'run_01', 'unweighted_events.lhe.gz'))
749+ else:
750+ misc.call(['run.sh', str(int(1.2*nb_event)), str(self.seed)], cwd=decay_dir)
751+ out[i] = lhe_parser.EventFile(pjoin(decay_dir, 'events.lhe.gz'))
752+ if cumul:
753+ break
754+
755+ if not output_width:
756+ return out
757+ else:
758+ return out, width
759+
760+ def run_onshell(self, line):
761+ """Run the onshell Algorithm"""
762+
763+ # 1. Read the event file to check which decay to perform and the number
764+ # of event to generate for each type of particle. (assume efficiency=1 for spin 0
765+ # otherwise efficiency=2
766+ # 2. Generate the associated events
767+ # 3. generate the various matrix-element (production/decay/production+decay)
768+
769+ # 3. comput
770+ # 3. perform the merge of the events.
771+ # if not enough events. re-generate the missing one.
772+ # First define an utility function for generating events when needed
773+
774+ args = self.split_arg(line)
775+
776+ #0. Define the path where to write the file
777+ self.path_me = os.path.realpath(self.options['curr_dir'])
778+ if self.options['ms_dir']:
779+ self.path_me = os.path.realpath(self.options['ms_dir'])
780+ if not os.path.exists(self.path_me):
781+ os.mkdir(self.path_me)
782+ else:
783+ # cleaning
784+ for name in misc.glob("decay_*_*", self.path_me):
785+ shutil.rmtree(name)
786+
787+ self.events_file.close()
788+ orig_lhe = lhe_parser.EventFile(self.events_file.name)
789+
790+ #count the number of particle need to be decayed.
791+ to_decay = collections.defaultdict(int)
792+ nb_event = 0
793+ for event in orig_lhe:
794+ nb_event +=1
795+ for particle in event:
796+ if particle.status == 1 and particle.pdg in self.final_state:
797+ # final state and tag as to decay
798+ to_decay[particle.pdg] += 1
799+ #misc.sprint(to_decay)
800+ #misc.sprint("import the mode -> temporary with logging")
801+ with misc.MuteLogger(["madgraph", "madevent", "ALOHA", "cmdprint"], [50,50,50,50]):
802+ mg5 = self.mg5cmd
803+ if not self.model:
804+ modelpath = self.model.get('modelpath+restriction')
805+ mg5.exec_cmd("import model %s" % modelpath)
806+ self.model = mg5._curr_model
807+
808+ # Handle the banner of the output file
809+ if not self.seed:
810+ self.seed = random.randint(0, int(30081*30081))
811+ self.do_set('seed %s' % self.seed)
812+ logger.info('Will use seed %s' % self.seed)
813+ self.history.insert(0, 'set seed %s' % self.seed)
814+
815+ if self.seed > 30081*30081: # can't use too big random number
816+ msg = 'Random seed too large ' + str(self.seed) + ' > 30081*30081'
817+ raise Exception, msg
818+
819+ self.options['seed'] = self.seed
820+
821+ text = '%s\n' % '\n'.join([ line for line in self.history if line])
822+ self.banner.add_text('madspin' , text)
823+
824+
825+ # 2. Generate the events requested
826+ nevents_for_max = self.options['Nevents_for_max_weigth']
827+ if nevents_for_max == 0 :
828+ nevents_for_max = 75
829+ nevents_for_max *= self.options['max_weight_ps_point']
830+
831+ with misc.MuteLogger(["madgraph", "madevent", "ALOHA", "cmdprint"], [50,50,50,50]):
832+ mg5 = self.mg5cmd
833+ if not self.model:
834+ modelpath = self.model.get('modelpath+restriction')
835+ mg5.exec_cmd("import model %s" % modelpath)
836+ evt_decayfile = {}
837+ br = 1.
838+ for pdg, nb_needed in to_decay.items():
839+ # muliply by expected effeciency of generation
840+ spin = self.model.get_particle(pdg).get('spin')
841+ if spin ==1:
842+ efficiency = 1.1
843+ else:
844+ efficiency = 2.0
845+
846+ totwidth = self.banner.get('param_card', 'decay', abs(pdg)).value
847+ #check if a splitting is needed
848+ if nb_needed == nb_event:
849+ nb_needed = int(efficiency*nb_needed) + nevents_for_max
850+ evt_decayfile[pdg], pwidth = self.generate_events(pdg, nb_needed, mg5, output_width=True)
851+ if pwidth > 1.01*totwidth:
852+ logger.warning('partial width (%s) larger than total width (%s) --from param_card--')
853+ elif pwidth > totwidth:
854+ pwidth = totwidth
855+ br = pwidth / totwidth
856+ elif nb_needed % nb_event == 0:
857+ nb_mult = nb_needed // nb_event
858+ nb_needed = int(efficiency*nb_needed) +nevents_for_max *nb_mult
859+ part = self.model.get_particle(pdg)
860+ name = part.get_name()
861+ if name not in self.list_branches:
862+ continue
863+ elif len(self.list_branches[name]) == nb_mult:
864+ evt_decayfile[pdg], pwidth = self.generate_events(pdg, nb_event, mg5, output_width=True)
865+ if pwidth > 1.01*totwidth:
866+ logger.warning('partial width (%s) larger than total width (%s) --from param_card--')
867+ elif pwidth > totwidth:
868+ pwidth = totwidth
869+ br = pwidth / totwidth**nb_mult
870+ br *= math.factorial(nb_mult)
871+ else:
872+ evt_decayfile[pdg],pwidth = self.generate_events(pdg, nb_needed, mg5, cumul=True, output_width=True)
873+ if pwidth > 1.01*totwidth:
874+ logger.warning('partial width (%s) larger than total width (%s) --from param_card--')
875+ elif pwidth > totwidth:
876+ pwidth = totwidth
877+ br *= (pwidth / totwidth)**nb_mult
878+ else:
879+ part = self.model.get_particle(pdg)
880+ name = part.get_name()
881+ if name not in self.list_branches or len(self.list_branches[name]) == 0:
882+ continue
883+ raise self.InvalidCmd("The onshell mode of MadSpin does not support event files where events do not *all* share the same set of final state particles to be decayed.")
884+
885+ self.branching_ratio = br
886+ self.efficiency = 1
887+ self.cross, self.error = self.banner.get_cross(witherror=True)
888+ self.cross *= self.branching_ratio
889+ self.error *= self.branching_ratio
890+
891+ # 3. generate the various matrix-element
892+ self.update_status('generating Madspin matrix element')
893+ self.generate_all = madspin.decay_all_events_onshell(self, self.banner, self.events_file,
894+ self.options)
895+ self.generate_all.compile()
896+ self.all_me = self.generate_all.all_me
897+ self.all_f2py = {}
898+
899+ #4. determine the maxwgt
900+ maxwgt = self.get_maxwgt_for_onshell(orig_lhe, evt_decayfile)
901+
902+
903+ #5. generate the decay
904+ orig_lhe.seek(0)
905+ output_lhe = lhe_parser.EventFile(orig_lhe.name.replace('.lhe', '_decayed.lhe'), 'w')
906+ self.banner.scale_init_cross(self.branching_ratio)
907+ self.banner.write(output_lhe, close_tag=False)
908+
909+
910+ self.efficiency =1.
911+ nb_try, nb_event = 0, len(orig_lhe)
912+
913+ start = time.time()
914+ for curr_event,production in enumerate(orig_lhe):
915+ if curr_event and curr_event % 1000 == 0 and float(str(curr_event)[1:]) ==0:
916+ print "decaying event number %s. Efficiency: %s [%s s]" % (curr_event, 1/self.efficiency, time.time()-start)
917+ while 1:
918+ nb_try +=1
919+ decays = self.get_decay_from_file(production, evt_decayfile, nb_event-curr_event)
920+ full_evt, wgt = self.get_onshell_evt_and_wgt(production, decays)
921+ if random.random()*maxwgt < wgt:
922+ break
923+ self.efficiency = curr_event/nb_try
924+ # change the weight associate to the event
925+ full_evt.wgt *= self.branching_ratio
926+ wgts = full_evt.parse_reweight()
927+ for key in wgts:
928+ wgts[key] *= self.branching_ratio
929+ output_lhe.write(str(full_evt))
930+
931+ output_lhe.write('</LesHouchesEvents>\n')
932+ self.efficiency = 1 # to let me5 to write the correct number of events
933+# misc.sprint('Done so far. output written in %s' % output_lhe.name)
934+
935+
936+ def get_decay_from_file(self,production, evt_decayfile, nb_remain):
937+ """return a dictionary PDG -> list of associated decay"""
938+
939+ out = collections.defaultdict(list)
940+ particles = [p for p in production if int(p.status) == 1.0]
941+ ids = [particle.pid for particle in particles]
942+ for i,particle in enumerate(particles):
943+ # check if we need to decay the particle
944+ if particle.pdg not in evt_decayfile:
945+ continue # nothing to do for this particle
946+ # check how the decay need to be done
947+ nb_decay = len(evt_decayfile[particle.pdg])
948+ if nb_decay == 0:
949+ continue #nothing to do for this particle
950+ # Determine the file to read in order to get the decay [decay_file]
951+ if nb_decay == 1:
952+ decay_file = evt_decayfile[particle.pdg][0]
953+ decay_file_nb = 0
954+ elif ids.count(particle.pdg) == nb_decay:
955+ decay_file = evt_decayfile[particle.pdg][ids[:i].count(particle.pdg)]
956+ decay_file_nb = ids[:i].count(particle.pdg)
957+ else:
958+ #need to select the file according to the associate cross-section
959+ r = random.random()
960+ tot = sum(evt_decayfile[particle.pdg][key].cross for key in evt_decayfile[particle.pdg])
961+ r = r * tot
962+ cumul = 0
963+ for j,events in evt_decayfile[particle.pdg].items():
964+
965+ cumul += events.cross
966+ if r < cumul:
967+ decay_file = events
968+ decay_file_nb = j
969+ break
970+ else:
971+ continue
972+ else:
973+ raise Exception
974+ # So now we know which file to read. Do it and re-generate events for that
975+ # file if needed.
976+ while 1:
977+ try:
978+ decay = decay_file.next()
979+ break
980+ except StopIteration:
981+ eff = self.efficiency
982+ needed = 1.05 * nb_remain / eff
983+ needed = min(50000, max(needed, 1000))
984+ with misc.MuteLogger(["madgraph", "madevent", "ALOHA", "cmdprint"], [50,50,50,50]):
985+ new_file = self.generate_events(particle.pdg, needed, self.mg5cmd, [decay_file_nb])
986+ evt_decayfile[particle.pdg].update(new_file)
987+ decay_file = evt_decayfile[particle.pdg][decay_file_nb]
988+ continue
989+ out[particle.pdg].append(decay)
990+
991+ return out
992+
993+
994+ def get_maxwgt_for_onshell(self, orig_lhe, evt_decayfile):
995+ """determine the maximum weight for the onshell (or similar) strategy"""
996+
997+ # event_decay is a dict pdg -> list of event file (contain the decay)
998+
999+
1000+ nevents = self.options['Nevents_for_max_weigth']
1001+ if nevents == 0 :
1002+ nevents = 75
1003+
1004+ all_maxwgt = []
1005+ logger.info("Estimating the maximum weight")
1006+ logger.info("*****************************")
1007+ logger.info("Probing the first %s events with %s phase space points" % (nevents, self.options['max_weight_ps_point']))
1008+
1009+
1010+ self.efficiency = 1. / self.options['max_weight_ps_point']
1011+ start = time.time()
1012+ for i in range(nevents):
1013+ if i % 5 ==1:
1014+ logger.info( "Event %s/%s : %2fs" % (i, nevents, time.time()-start))
1015+ maxwgt = 0
1016+ orig_lhe.seek(0)
1017+ base_event = orig_lhe.next()
1018+ for j in range(self.options['max_weight_ps_point']):
1019+ decays = self.get_decay_from_file(base_event, evt_decayfile, nevents-i)
1020+ #carefull base_event is modified by the following function
1021+ _, wgt = self.get_onshell_evt_and_wgt(base_event, decays)
1022+ maxwgt = max(wgt, maxwgt)
1023+ all_maxwgt.append(maxwgt)
1024+
1025+ all_maxwgt.sort(reverse=True)
1026+ assert all_maxwgt[0] >= all_maxwgt[1]
1027+ decay_tools=madspin.decay_misc()
1028+ ave_weight, std_weight = decay_tools.get_mean_sd(all_maxwgt)
1029+ std_weight=math.sqrt(std_weight)
1030+ base_max_weight = 1.05 * (ave_weight+self.options['nb_sigma']*std_weight)
1031+
1032+# misc.sprint(all_maxwgt)
1033+ for i in [20, 30, 40, 50]:
1034+ if len(all_maxwgt) < i:
1035+ break
1036+ ave_weight, std_weight = decay_tools.get_mean_sd(all_maxwgt[:i])
1037+ std_weight=math.sqrt(std_weight)
1038+ base_max_weight = max(base_max_weight, 1.05 * (ave_weight+self.options['nb_sigma']*std_weight))
1039+
1040+ if all_maxwgt[1] > base_max_weight:
1041+ base_max_weight = 1.05 * all_maxwgt[1]
1042+ return base_max_weight
1043+
1044+
1045+
1046+
1047+
1048+ def get_onshell_evt_and_wgt(self, production, decays):
1049+ """ return the onshell wgt for the production event associated to the decays
1050+ return also the full event with decay.
1051+ Carefull this modifies production event (pass to the full one)"""
1052+
1053+ tag, order = production.get_tag_and_order()
1054+ try:
1055+ info = self.generate_all.all_me[tag]
1056+ except:
1057+ misc.sprint(self.generate_all.all_me)
1058+ raise
1059+ import copy
1060+
1061+
1062+ if hasattr(production, 'me_wgt'):
1063+ production_me = production.me_wgt
1064+ else:
1065+ production_me = self.calculate_matrix_element(production)
1066+ production.me_wgt = production_me
1067+
1068+ decay_me = 1.0
1069+ for pdg in decays:
1070+ for dec in decays[pdg]:
1071+ decay_me *= self.calculate_matrix_element(dec)
1072+ random.shuffle(decays[pdg])
1073+
1074+ full_event = lhe_parser.Event(str(production))
1075+ full_event = full_event.add_decays(decays)
1076+ full_me = self.calculate_matrix_element(full_event)
1077+
1078+# misc.sprint([p.pdg for p in production])
1079+# misc.sprint([p.pdg for p in full_event])
1080+# misc.sprint(full_me, production_me, decay_me)
1081+
1082+ return full_event, full_me/(production_me*decay_me)
1083+
1084+
1085+ def calculate_matrix_element(self, event):
1086+ """routine to return the matrix element"""
1087+
1088+ tag, order = event.get_tag_and_order()
1089+ orig_order = self.all_me[tag]['order']
1090+ pdir = self.all_me[tag]['pdir']
1091+ if pdir in self.all_f2py:
1092+ p = event.get_momenta(orig_order)
1093+ p = rwgt_interface.ReweightInterface.invert_momenta(p)
1094+ return self.all_f2py[pdir](p, event.aqcd, 0)
1095+ else:
1096+ if sys.path[0] != pjoin(self.path_me, 'madspin_me', 'SubProcesses'):
1097+ sys.path.insert(0, pjoin(self.path_me, 'madspin_me', 'SubProcesses'))
1098+
1099+ mymod = __import__("%s.matrix2py" % (pdir))
1100+ reload(mymod)
1101+ mymod = getattr(mymod, 'matrix2py')
1102+ with misc.chdir(pjoin(self.path_me, 'madspin_me', 'SubProcesses', pdir)):
1103+ with misc.stdchannel_redirected(sys.stdout, os.devnull):
1104+ mymod.initialise(pjoin(self.path_me, 'Cards','param_card.dat'))
1105+ self.all_f2py[pdir] = mymod.get_me
1106+ return self.calculate_matrix_element(event)
1107+
1108+
1109+ def generate_all_matrix_element(self):
1110+
1111+ # 1. compute the production matrix element -----------------------------
1112+ processes = [line[9:].strip() for line in self.banner.proc_card
1113+ if line.startswith('generate')]
1114+ processes += [' '.join(line.split()[2:]) for line in self.banner.proc_card
1115+ if re.search('^\s*add\s+process', line)]
1116+ # 2. compute the decay matrix-element
1117+ decay_text = []
1118+ processes_decay = []
1119+ for decays in self.list_branches.values():
1120+ for decay in decays:
1121+ if '=' not in decay:
1122+ decay += ' QCD=99'
1123+ if ',' in decay:
1124+ decay_text.append('(%s)' % decay)
1125+ else:
1126+ decay_text.append(decay)
1127+ processes_decay.append(decay)
1128+ decay_text = ', '.join(decay_text)
1129+ processes += []
1130+
1131+ #handle NLO
1132+ new_processes = []
1133+ for proc in processes:
1134+ # deal with @ syntax need to move it after the decay specification
1135+ if '@' in proc:
1136+ proc, proc_nb = proc.split('@')
1137+ try:
1138+ proc_nb = int(proc_nb)
1139+ except ValueError:
1140+ raise MadSpinError, 'MadSpin didn\'t allow order restriction after the @ comment: \"%s\" not valid' % proc_nb
1141+ proc_nb = '@ %i' % proc_nb
1142+ else:
1143+ proc_nb = ''
1144+
1145+ rwgt_interface.ReweightInterface.get_LO_definition_from_NLO()
1146+
1147+
1148+
1149+
1150 if __name__ == '__main__':
1151
1152 a = MadSpinInterface()
1153
1154=== modified file 'Template/Common/Cards/madspin_card_default.dat'
1155--- Template/Common/Cards/madspin_card_default.dat 2013-11-13 03:38:29 +0000
1156+++ Template/Common/Cards/madspin_card_default.dat 2017-03-08 10:27:27 +0000
1157@@ -7,14 +7,18 @@
1158 #* The MadGraph5_aMC@NLO Development Team - Find us at *
1159 #* https://server06.fynu.ucl.ac.be/projects/madgraph *
1160 #* *
1161+#* Manual: *
1162+#* cp3.irmp.ucl.ac.be/projects/madgraph/wiki/MadSpin *
1163+#* *
1164 #************************************************************
1165 #Some options (uncomment to apply)
1166 #
1167 # set seed 1
1168 # set Nevents_for_max_weigth 75 # number of events for the estimate of the max. weight
1169-# set BW_cut 15 # cut on how far the particle can be off-shell
1170+# set BW_cut 15 # cut on how far the particle can be off-shell
1171+# set spinmode onshell # Use one of the madspin special mode
1172 set max_weight_ps_point 400 # number of PS to estimate the maximum for each event
1173-#
1174+
1175 # specify the decay for the final state particles
1176 decay t > w+ b, w+ > all all
1177 decay t~ > w- b~, w- > all all
1178
1179=== modified file 'Template/LO/Cards/pythia8_card_default.dat'
1180--- Template/LO/Cards/pythia8_card_default.dat 2016-09-07 21:34:46 +0000
1181+++ Template/LO/Cards/pythia8_card_default.dat 2017-03-08 10:27:27 +0000
1182@@ -57,12 +57,18 @@
1183 Merging:TMS = -1.0
1184 ! This must be set manually, according to Pythia8 directives.
1185 ! An example of possible value is 'pp>LEPTONS,NEUTRINOS'
1186+! Alternatively, from Pythia v8.223 onwards, the value 'guess' can be
1187+! used to instruct Pythia to guess the hard process. The guess would mean
1188+! that all particles apart from light partons will be considered as a part
1189+! of the hard process. This guess is prone to errors if the desired hard
1190+! process is complicated (i.e. contains light partons). The user should
1191+! then be wary of suspicious error messages in the Pythia log file.
1192 Merging:Process = <set_by_user>
1193 ! A value of -1 means that it is automatically guessed by MadGraph.
1194 ! It is however always safer to explicitly set it.
1195 Merging:nJetMax = -1
1196 !
1197-! For all merging schemes, decide wehter you want the merging scale
1198+! For all merging schemes, decide whehter you want the merging scale
1199 ! variation computed for only the central weights or all other
1200 ! PDF and scale variation weights as well
1201 SysCalc:fullCutVariation = off
1202
1203=== modified file 'Template/LO/SubProcesses/makefile'
1204--- Template/LO/SubProcesses/makefile 2016-11-16 23:59:06 +0000
1205+++ Template/LO/SubProcesses/makefile 2017-03-08 10:27:27 +0000
1206@@ -43,8 +43,8 @@
1207 $(PROG): $(PROCESS) auto_dsig.o $(LIBS)
1208 $(FC) -o $(PROG) $(PROCESS) $(LINKLIBS) $(LDFLAGS) $(BIASDEPENDENCIES)
1209
1210-gensym: $(SYMMETRY) configs.inc $(LIBDIR)libmodel.$(libext) $(LIBDIR)libgeneric.$(libext)
1211- $(FC) -o gensym $(SYMMETRY) -L../../lib/ -lmodel -lgeneric -lpdf $(LDFLAGS)
1212+gensym: $(SYMMETRY) configs.inc $(LIBS)
1213+ $(FC) -o gensym $(SYMMETRY) $(LINKLIBS) $(LDFLAGS) $(BIASDEPENDENCIES)
1214
1215 $(LIBDIR)libmodel.$(libext): ../../Cards/param_card.dat
1216 cd ../../Source/MODEL; make
1217
1218=== modified file 'Template/LO/SubProcesses/myamp.f'
1219--- Template/LO/SubProcesses/myamp.f 2016-10-03 09:56:24 +0000
1220+++ Template/LO/SubProcesses/myamp.f 2017-03-08 10:27:27 +0000
1221@@ -273,9 +273,6 @@
1222 if (onshell .and. (lbw(nbw).eq. 2) .or.
1223 $ .not. onshell .and. (lbw(nbw).eq. 1)) then
1224 cut_bw=.true.
1225- if (gForceBW(i, iconfig).eq.1) then
1226- return
1227- endif
1228 c write(*,*) 'cut_bw: ',nbw,xmass,onshell,lbw(nbw),cut_bw
1229 endif
1230 endif
1231
1232=== modified file 'Template/LO/bin/internal/gen_jpeg-pl'
1233--- Template/LO/bin/internal/gen_jpeg-pl 2014-03-07 12:07:33 +0000
1234+++ Template/LO/bin/internal/gen_jpeg-pl 2017-03-08 10:27:27 +0000
1235@@ -26,7 +26,7 @@
1236 }
1237 close(OUT);
1238 close(IN);
1239- system "/bin/bash -c \"nice gs \-sDEVICE\=jpeg \-sOutputFile\=matrix$imatrix\%00d.jpg \-q \-dNOPAUSE \-dBATCH matrix-1.ps\"";
1240+ system "/bin/bash -c \"nice gs \-sDEVICE\=jpeg \-sOutputFile\=matrix$imatrix\%00d.jpg \-q \-dNOPAUSE \-dBATCH matrix-1.ps > /dev/null\"";
1241 system "rm -f matrix-1.ps";
1242
1243 # Determine how many jpg files we have
1244@@ -72,7 +72,7 @@
1245
1246 system ("/bin/bash -c \"cat matrix$imatrix.ps | sed 1,352d >> junk.ps\" ");
1247
1248- system "/bin/bash -c \"nice gs \-sDEVICE\=jpeg \-sOutputFile\=card.jpg \-q \-dNOPAUSE \-dBATCH \-g180x150 ./junk.ps; rm -f junk.ps; cp -p card.jpg ../../HTML/card.jpg\" ";
1249+ system "/bin/bash -c \"nice gs \-sDEVICE\=jpeg \-sOutputFile\=card.jpg \-q \-dNOPAUSE \-dBATCH \-g180x150 ./junk.ps; rm -f junk.ps; cp -p card.jpg ../../HTML/card.jpg > /dev/null\" ";
1250 }
1251 if ($imatrix eq "") {$imatrix = 0;}
1252 $imatrix = $imatrix + 1;
1253
1254=== modified file 'Template/NLO/Cards/FO_analyse_card.dat'
1255--- Template/NLO/Cards/FO_analyse_card.dat 2015-03-06 18:09:36 +0000
1256+++ Template/NLO/Cards/FO_analyse_card.dat 2017-03-08 10:27:27 +0000
1257@@ -9,7 +9,8 @@
1258 #
1259 #######################################################################
1260 #
1261-# Analysis format. Can either be 'topdrawer', 'root', 'HwU' or 'none'.
1262+# Analysis format.
1263+# Can either be 'topdrawer', 'root', 'HwU', 'LHE' or 'none'.
1264 # When choosing HwU, it comes with a GnuPlot wrapper. When choosing
1265 # topdrawer, the histogramming package 'dbook.f' is included in the
1266 # code, while when choosing root the 'rbook_fe8.f' and 'rbook_be8.cc'
1267@@ -17,6 +18,7 @@
1268 # to be set empty.
1269 FO_ANALYSIS_FORMAT = HwU
1270 #
1271+#
1272 # Needed extra-libraries (FastJet is already linked):
1273 FO_EXTRALIBS =
1274 #
1275
1276=== modified file 'Template/NLO/FixedOrderAnalysis/HwU.f'
1277--- Template/NLO/FixedOrderAnalysis/HwU.f 2016-02-18 14:05:45 +0000
1278+++ Template/NLO/FixedOrderAnalysis/HwU.f 2017-03-08 10:27:27 +0000
1279@@ -47,11 +47,12 @@
1280 c input 2: Sum PS points for a given iteration and error estimate by
1281 c square root of the sum of the squares. Perform a weighted average
1282 c iteration-by-iteration
1283+c input 3: Same as input 2, but weighted average is same as from MINT
1284 implicit none
1285 integer input
1286 integer error_estimation
1287 common /HwU_common2/ error_estimation
1288- if (input.ge.0 .and. input.le.2) then
1289+ if (input.ge.0 .and. input.le.3) then
1290 error_estimation=input
1291 else
1292 write (*,*) 'unknown error estimation',input
1293@@ -68,7 +69,7 @@
1294 c (approx. 110 MB).
1295 integer error_estimation
1296 common /HwU_common2/ error_estimation
1297- data error_estimation /1/
1298+ data error_estimation /3/
1299 end
1300
1301 c Book the histograms at the start of the run. Give a 'label' (an
1302@@ -190,19 +191,20 @@
1303 c uncertainty estimate given in 'histy_err' and empties the arrays for
1304 c the current iteration so that they can be filled with the next
1305 c iteration.
1306- subroutine HwU_accum_iter(inclde,nPSpoints)
1307+ subroutine HwU_accum_iter(inclde,nPSpoints,values)
1308 implicit none
1309 include "HwU.inc"
1310 logical inclde
1311 integer nPSpoints,label,i,j
1312 double precision nPSinv,etot,vtot(max_wgts),niter,y_squared
1313+ $ ,values(2)
1314 data niter /0d0/
1315 nPSinv = 1d0/dble(nPSpoints)
1316 if (inclde) niter = niter+1d0
1317 do label=1,max_plots
1318 if (.not. booked(label)) cycle
1319 if (inclde) then
1320- call accumulate_results(label,nPSinv,niter)
1321+ call accumulate_results(label,nPSinv,niter,values)
1322 endif
1323 c Reset the histo of the current iteration to zero so that they are
1324 c ready for the next iteration.
1325@@ -227,7 +229,7 @@
1326 implicit none
1327 include "HwU.inc"
1328 integer label,nPSpoints,i,j
1329- double precision nPSinv,niter
1330+ double precision nPSinv,niter,dummy(2)
1331 nPSinv=1d0/dble(nPSpoints)
1332 niter=1d0
1333 do label=1,max_plots
1334@@ -239,7 +241,7 @@
1335 enddo
1336 histy_err(label,i)=0d0
1337 enddo
1338- call accumulate_results(label,nPSinv,niter)
1339+ call accumulate_results(label,nPSinv,niter,dummy)
1340 enddo
1341 return
1342 end
1343@@ -254,11 +256,12 @@
1344 c uncertainty. Note that this means that during the filling of the
1345 c histograms the central value should not be zero if any of the other
1346 c weights are non-zero.
1347- subroutine accumulate_results(label,nPSinv,niter)
1348+ subroutine accumulate_results(label,nPSinv,niter,values)
1349 implicit none
1350 include "HwU.inc"
1351 integer label,i,j
1352 double precision nPSinv,etot,vtot(max_wgts),niter,y_squared
1353+ $ ,values(2),a1,a2
1354 integer error_estimation
1355 common /HwU_common2/ error_estimation
1356 if (error_estimation.eq.2) then
1357@@ -281,7 +284,7 @@
1358 etot=etot* sqrt(dble(histi(label,i))
1359 & /(dble(histi(label,i))-1.5d0))
1360 else
1361- etot=0.999d49
1362+ etot=abs(vtot(1))*10d0 ! multiply by 10 to make it large
1363 endif
1364 c If the error estimation of the accumulated results is still zero
1365 c (i.e. no points were added yet, e.g. because it is the first
1366@@ -303,6 +306,47 @@
1367 $ 1d0/sqrt(1d0/histy_err(label,i)**2+1d0/etot**2)
1368 endif
1369 enddo
1370+ elseif (error_estimation.eq.3) then
1371+ do i=1,nbin(label)
1372+c Skip bin if no entries
1373+ if (histi(label,i).eq.0) cycle
1374+c Divide weights by the number of PS points. This means that this is
1375+c now normalised to the total cross section in that bin
1376+ do j=1,nwgts
1377+ vtot(j)=histy(j,label,i)*nPSinv
1378+ enddo
1379+c Error estimation of the current bin
1380+ etot=sqrt(abs(histy2(label,i)*nPSinv-vtot(1)**2)*nPSinv)
1381+c Include "Bessel's correction" to have a corrected (even though
1382+c still biased) estimator of the standard deviation.
1383+ if (histi(label,i).gt.1) then
1384+ etot=etot* sqrt(dble(histi(label,i))
1385+ & /(dble(histi(label,i))-1.5d0))
1386+ else
1387+ etot=abs(vtot(1))*10d0 ! multiply by 10 to make it large
1388+ endif
1389+c If the error estimation of the accumulated results is still zero
1390+c (i.e. no points were added yet, e.g. because it is the first
1391+c iteration) simply copy the results of this iteration over the
1392+c accumulated results.
1393+ if (histy_err(label,i).eq.0d0) then
1394+ do j=1,nwgts
1395+ histy_acc(j,label,i)=vtot(j)
1396+ enddo
1397+ histy_err(label,i)=etot
1398+ else
1399+c Add the results of the current iteration to the accumulated results
1400+ do j=1,nwgts
1401+ histy_acc(j,label,i)=(histy_acc(j,label,i)
1402+ & /values(2)+vtot(j)/values(1))/(1d0
1403+ & /values(2) + 1d0/values(1))
1404+ enddo
1405+ a1=((1d0/values(1))/((1d0/values(1))+1d0/values(2)))**2
1406+ a2=((1d0/values(2))/((1d0/values(1))+1d0/values(2)))**2
1407+ histy_err(label,i)=sqrt(a2*histy_err(label,i)**2 +
1408+ & a1*etot**2)
1409+ endif
1410+ enddo
1411 elseif(error_estimation.eq.1) then
1412 c simply sum the weights in the bins
1413 do i=1,nbin(label)
1414
1415=== modified file 'Template/NLO/FixedOrderAnalysis/analysis_HwU_pp_lplm.f'
1416--- Template/NLO/FixedOrderAnalysis/analysis_HwU_pp_lplm.f 2016-02-17 14:32:27 +0000
1417+++ Template/NLO/FixedOrderAnalysis/analysis_HwU_pp_lplm.f 2017-03-08 10:27:27 +0000
1418@@ -136,67 +136,67 @@
1419 detallb=etal-etalb
1420 c
1421 l=0
1422- call HwU_fill(l+1,(ptv),(WGTS))
1423- call HwU_fill(l+2,(ptv),(WGTS))
1424- if(ptv.gt.0.d0)call HwU_fill(l+3,(log10(ptv)),(WGTS))
1425- call HwU_fill(l+4,(yv),(WGTS))
1426- call HwU_fill(l+5,(etav),(WGTS))
1427- call HwU_fill(l+6,(xmv),(WGTS))
1428-c
1429- call HwU_fill(l+7,(ptl),(WGTS))
1430- call HwU_fill(l+8,(ptl),(WGTS))
1431- if(ptl.gt.0.d0)call HwU_fill(l+9,(log10(ptl)),(WGTS))
1432- call HwU_fill(l+10,(etal),(WGTS))
1433- call HwU_fill(l+11,(ptlb),(WGTS))
1434- call HwU_fill(l+12,(ptlb),(WGTS))
1435- if(ptlb.gt.0.d0)call HwU_fill(l+13,(log10(ptlb)),(WGTS))
1436- call HwU_fill(l+14,(etalb),(WGTS))
1437-c
1438- call HwU_fill(l+15,(detallb),(WGTS))
1439- call HwU_fill(l+16,(azi),(WGTS))
1440- if(azinorm.gt.0.d0) call HwU_fill(l+17,(log10(azinorm)),(WGTS))
1441- call HwU_fill(l+18,(xmll),(WGTS))
1442- call HwU_fill(l+19,(ptpair),(WGTS))
1443- if(ptpair.gt.0)call HwU_fill(l+20,(log10(ptpair)),(WGTS))
1444- call HwU_fill(l+21,(0d0),(WGTS))
1445+ call HwU_fill(l+1,(ptv),WGTS)
1446+ call HwU_fill(l+2,(ptv),WGTS)
1447+ if(ptv.gt.0.d0)call HwU_fill(l+3,(log10(ptv)),WGTS)
1448+ call HwU_fill(l+4,(yv),WGTS)
1449+ call HwU_fill(l+5,(etav),WGTS)
1450+ call HwU_fill(l+6,(xmv),WGTS)
1451+c
1452+ call HwU_fill(l+7,(ptl),WGTS)
1453+ call HwU_fill(l+8,(ptl),WGTS)
1454+ if(ptl.gt.0.d0)call HwU_fill(l+9,(log10(ptl)),WGTS)
1455+ call HwU_fill(l+10,(etal),WGTS)
1456+ call HwU_fill(l+11,(ptlb),WGTS)
1457+ call HwU_fill(l+12,(ptlb),WGTS)
1458+ if(ptlb.gt.0.d0)call HwU_fill(l+13,(log10(ptlb)),WGTS)
1459+ call HwU_fill(l+14,(etalb),WGTS)
1460+c
1461+ call HwU_fill(l+15,(detallb),WGTS)
1462+ call HwU_fill(l+16,(azi),WGTS)
1463+ if(azinorm.gt.0.d0) call HwU_fill(l+17,(log10(azinorm)),WGTS)
1464+ call HwU_fill(l+18,(xmll),WGTS)
1465+ call HwU_fill(l+19,(ptpair),WGTS)
1466+ if(ptpair.gt.0)call HwU_fill(l+20,(log10(ptpair)),WGTS)
1467+ call HwU_fill(l+21,(0d0),WGTS)
1468 c
1469 l=l+21
1470
1471 if(abs(etav).lt.ycut)then
1472- call HwU_fill(l+1,(ptv),(WGTS))
1473- call HwU_fill(l+2,(ptv),(WGTS))
1474- if(ptv.gt.0.d0)call HwU_fill(l+3,(log10(ptv)),(WGTS))
1475+ call HwU_fill(l+1,(ptv),WGTS)
1476+ call HwU_fill(l+2,(ptv),WGTS)
1477+ if(ptv.gt.0.d0)call HwU_fill(l+3,(log10(ptv)),WGTS)
1478 endif
1479 if(ptv.gt.20.d0)then
1480- call HwU_fill(l+4,(yv),(WGTS))
1481- call HwU_fill(l+5,(etav),(WGTS))
1482+ call HwU_fill(l+4,(yv),WGTS)
1483+ call HwU_fill(l+5,(etav),WGTS)
1484 endif
1485 if(abs(etav).lt.ycut.and.ptv.gt.20.d0)then
1486- call HwU_fill(l+6,(xmv),(WGTS))
1487- call HwU_fill(l+21,(0d0),(WGTS))
1488+ call HwU_fill(l+6,(xmv),WGTS)
1489+ call HwU_fill(l+21,(0d0),WGTS)
1490 endif
1491 c
1492 if(abs(etal).lt.ycut)then
1493- call HwU_fill(l+7,(ptl),(WGTS))
1494- call HwU_fill(l+8,(ptl),(WGTS))
1495- if(ptl.gt.0.d0)call HwU_fill(l+9,(log10(ptl)),(WGTS))
1496+ call HwU_fill(l+7,(ptl),WGTS)
1497+ call HwU_fill(l+8,(ptl),WGTS)
1498+ if(ptl.gt.0.d0)call HwU_fill(l+9,(log10(ptl)),WGTS)
1499 endif
1500- if(ptl.gt.20.d0)call HwU_fill(l+10,(etal),(WGTS))
1501+ if(ptl.gt.20.d0)call HwU_fill(l+10,(etal),WGTS)
1502 if(abs(etalb).lt.ycut)then
1503- call HwU_fill(l+11,(ptlb),(WGTS))
1504- call HwU_fill(l+12,(ptlb),(WGTS))
1505- if(ptlb.gt.0.d0)call HwU_fill(l+13,(log10(ptlb)),(WGTS))
1506+ call HwU_fill(l+11,(ptlb),WGTS)
1507+ call HwU_fill(l+12,(ptlb),WGTS)
1508+ if(ptlb.gt.0.d0)call HwU_fill(l+13,(log10(ptlb)),WGTS)
1509 endif
1510- if(ptlb.gt.20.d0)call HwU_fill(l+14,(etalb),(WGTS))
1511+ if(ptlb.gt.20.d0)call HwU_fill(l+14,(etalb),WGTS)
1512 c
1513 if( abs(etal).lt.ycut.and.abs(etalb).lt.ycut .and.
1514 & ptl.gt.20.d0.and.ptlb.gt.20.d0)then
1515- call HwU_fill(l+15,(detallb),(WGTS))
1516- call HwU_fill(l+16,(azi),(WGTS))
1517- if(azinorm.gt.0.d0) call HwU_fill(l+17,(log10(azinorm)),(WGTS))
1518- call HwU_fill(l+18,(xmll),(WGTS))
1519- call HwU_fill(l+19,(ptpair),(WGTS))
1520- if(ptpair.gt.0) call HwU_fill(l+20,(log10(ptpair)),(WGTS))
1521+ call HwU_fill(l+15,(detallb),WGTS)
1522+ call HwU_fill(l+16,(azi),WGTS)
1523+ if(azinorm.gt.0.d0) call HwU_fill(l+17,(log10(azinorm)),WGTS)
1524+ call HwU_fill(l+18,(xmll),WGTS)
1525+ call HwU_fill(l+19,(ptpair),WGTS)
1526+ if(ptpair.gt.0) call HwU_fill(l+20,(log10(ptpair)),WGTS)
1527 endif
1528
1529 999 return
1530
1531=== modified file 'Template/NLO/MCatNLO/HWAnalyzer/hw6an_HwU_pp_V.f'
1532--- Template/NLO/MCatNLO/HWAnalyzer/hw6an_HwU_pp_V.f 2016-03-21 08:45:42 +0000
1533+++ Template/NLO/MCatNLO/HWAnalyzer/hw6an_HwU_pp_V.f 2017-03-08 10:27:27 +0000
1534@@ -125,7 +125,7 @@
1535 ENDIF
1536 c
1537 c CHOOSE IDENT=24 FOR W+, IDENT=-24 FOR W-, IDENT=23 FOR Z0
1538- IDENT=23
1539+ IDENT=24
1540 C INCOMING PARTONS MAY TRAVEL IN THE SAME DIRECTION: IT''S A POWER-SUPPRESSED
1541 C EFFECT, SO THROW THE EVENT AWAY
1542 IF(SIGN(1.D0,PHEP(3,4)).EQ.SIGN(1.D0,PHEP(3,5)))THEN
1543
1544=== modified file 'Template/NLO/MCatNLO/shower_template.sh'
1545--- Template/NLO/MCatNLO/shower_template.sh 2016-10-27 14:53:25 +0000
1546+++ Template/NLO/MCatNLO/shower_template.sh 2017-03-08 10:27:27 +0000
1547@@ -7,7 +7,7 @@
1548 RUN_NAME=$3
1549 NFILE=$4
1550
1551-export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%(extralibs)s
1552+export %(ld_library_path)s=$%(ld_library_path)s:%(extralibs)s
1553
1554 # this is for py8 runs
1555 export PYTHIA8DATA=`pwd`/xmldoc
1556
1557=== modified file 'Template/NLO/MCatNLO/srcHerwig/madfks_hwlhin.f'
1558--- Template/NLO/MCatNLO/srcHerwig/madfks_hwlhin.f 2016-11-13 13:28:20 +0000
1559+++ Template/NLO/MCatNLO/srcHerwig/madfks_hwlhin.f 2017-03-08 10:27:27 +0000
1560@@ -85,7 +85,6 @@
1561 call read_rwgt_line_wgt(iunit,ww(iww))
1562 enddo
1563 read(iunit,'(a)')string ! </rwgt>
1564- write(*,*) string
1565 endif
1566 do while(index(string,'</event>').eq.0)
1567 read(iunit,'(a)')string ! <rwgt>
1568
1569=== modified file 'Template/NLO/Source/ranmar.f'
1570--- Template/NLO/Source/ranmar.f 2014-06-12 08:52:03 +0000
1571+++ Template/NLO/Source/ranmar.f 2017-03-08 10:27:27 +0000
1572@@ -1,10 +1,9 @@
1573 function ran2()
1574 c Wrapper for the random numbers; needed for the NLO stuff
1575 implicit none
1576+ include '../SubProcesses/mint.inc' ! includes iconfig common
1577 double precision ran2,x,a,b
1578 integer ii,jconfig
1579- integer iconfig
1580- common/to_configs/iconfig
1581 a=0d0 ! min allowed value for x
1582 b=1d0 ! max allowed value for x
1583 ii=0 ! dummy argument of ntuple
1584@@ -194,6 +193,8 @@
1585 c Arguments
1586 c
1587 integer iseed
1588+ integer random_offset_split
1589+ common /c_random_offset_split/ random_offset_split
1590 c
1591 c Local
1592 c
1593@@ -207,7 +208,7 @@
1594 close(lun)
1595 return
1596 14 close(lun)
1597- 25 iseed = 0
1598+ 25 iseed = random_offset_split
1599 end
1600
1601 subroutine ranmar(rvec)
1602
1603=== modified file 'Template/NLO/Source/run.inc'
1604--- Template/NLO/Source/run.inc 2016-09-08 23:15:34 +0000
1605+++ Template/NLO/Source/run.inc 2017-03-08 10:27:27 +0000
1606@@ -79,4 +79,8 @@
1607 common/to_rwgt/ do_rwgt_scale, rw_Fscale_down, rw_Fscale_up, rw_Rscale_down, rw_Rscale_up,
1608 # do_rwgt_pdf, pdf_set_min, pdf_set_max,
1609 # store_rwgt_info
1610-
1611+c
1612+c For FO run (with lhe type of analysis
1613+c
1614+ double precision FO_LHE_weight_ratio
1615+ common /FO_ANALYSIS_LHW/FO_LHE_weight_ratio
1616\ No newline at end of file
1617
1618=== modified file 'Template/NLO/SubProcesses/HwU_dummy.f'
1619--- Template/NLO/SubProcesses/HwU_dummy.f 2015-03-05 16:12:37 +0000
1620+++ Template/NLO/SubProcesses/HwU_dummy.f 2017-03-08 10:27:27 +0000
1621@@ -8,7 +8,8 @@
1622 subroutine HwU_add_points
1623 end
1624
1625- subroutine HwU_accum_iter(ldummy,idummy)
1626+ subroutine HwU_accum_iter(ldummy,idummy,dummy)
1627 logical ldummy
1628 integer idummy
1629+ double precision dummy(2)
1630 end
1631
1632=== modified file 'Template/NLO/SubProcesses/ajob_template'
1633--- Template/NLO/SubProcesses/ajob_template 2015-09-25 14:53:36 +0000
1634+++ Template/NLO/SubProcesses/ajob_template 2017-03-08 10:27:27 +0000
1635@@ -34,7 +34,11 @@
1636 TAGTAGTAGTAGTAGTAGTAG for i in 1 ; do
1637
1638 if [[ $run_mode == 'all' || $run_mode == 'born' ]] ; then
1639- j=$run_mode\_G$i
1640+ if [[ $runnumber == '0' ]] ; then
1641+ j=$run_mode\_G$i
1642+ else
1643+ j=$run_mode\_G$i\_$runnumber
1644+ fi
1645 else
1646 if [[ $runnumber == '0' ]] ; then
1647 j=G$run_mode$i
1648
1649=== added file 'Template/NLO/SubProcesses/analysis_lhe.f'
1650--- Template/NLO/SubProcesses/analysis_lhe.f 1970-01-01 00:00:00 +0000
1651+++ Template/NLO/SubProcesses/analysis_lhe.f 2017-03-08 10:27:27 +0000
1652@@ -0,0 +1,222 @@
1653+c LHE analysis routines used when having fo_analysis_format=lhe in the
1654+c FO_analyse_card.
1655+c that card also defines FO_LHE_WEIGHT which is a minimal weight to write the
1656+c event (event with lower weights will be un-weighted)
1657+
1658+ subroutine analysis_begin(nwgt,weights_info)
1659+ implicit none
1660+ integer nwgt
1661+ character*(*) weights_info(*)
1662+ integer nwgts,nevents
1663+ double precision sum_of_wgts
1664+ common/to_lhe_analysis/sum_of_wgts,nwgts,nevents
1665+ logical lopen
1666+ nwgts=nwgt
1667+ sum_of_wgts=0d0
1668+ nevents=0
1669+ inquire(41,OPENED=lopen) ! in case run is reset due to 2 bad iterations...
1670+ if (lopen) close(41)
1671+ open(41,file= 'events.lhe',status='UNKNOWN')
1672+ write (41,'(a)') '<eventgroup>'
1673+ end
1674+
1675+ subroutine analysis_end(xnorm)
1676+ implicit none
1677+ double precision xnorm
1678+ integer nwgts,nevents
1679+ double precision sum_of_wgts
1680+ common/to_lhe_analysis/sum_of_wgts,nwgts,nevents
1681+ logical lopen
1682+ integer npoints
1683+ double precision cross_section
1684+ common /for_FixedOrder_lhe/ cross_section,npoints
1685+ inquire(41,OPENED=lopen) ! safety
1686+ if (lopen) then
1687+ backspace(41) ! overwrite the final </eventgroup> tag
1688+ write (41,*) nevents,sum_of_wgts,cross_section
1689+ close(41)
1690+ open(41, file='header.txt')
1691+ call write_lhef_header(41, 0, 'FO')
1692+ close(41)
1693+ endif
1694+ end
1695+
1696+ subroutine analysis_fill(p,istatus,ipdg,wgts,ibody)
1697+ implicit none
1698+ include 'nexternal.inc'
1699+ include 'reweight.inc'
1700+ include 'run.inc'
1701+ integer nwgt,max_weight
1702+ parameter (max_weight=maxscales*maxscales+maxpdfs+1)
1703+c include 'genps.inc'
1704+ integer istatus(nexternal)
1705+ integer iPDG(nexternal)
1706+ double precision p(0:4,nexternal)
1707+ double precision wgts(max_weight)
1708+ integer ibody
1709+ integer nwgts,nevents
1710+ double precision sum_of_wgts
1711+ common/to_lhe_analysis/sum_of_wgts,nwgts,nevents
1712+c
1713+ integer i,j,npart
1714+ double precision ran2
1715+ external ran2
1716+ double precision R,twgt
1717+ double precision zero
1718+ integer izero
1719+ parameter (zero=0.d0)
1720+ parameter (izero=0)
1721+ include 'nFKSconfigs.inc'
1722+ INTEGER NFKSPROCESS
1723+ COMMON/C_NFKSPROCESS/NFKSPROCESS
1724+ integer iSorH_lhe,ifks_lhe(fks_configs) ,jfks_lhe(fks_configs)
1725+ & ,fksfather_lhe(fks_configs) ,ipartner_lhe(fks_configs)
1726+ double precision scale1_lhe(fks_configs),scale2_lhe(fks_configs)
1727+ common/cto_LHE1/iSorH_lhe,ifks_lhe,jfks_lhe, fksfather_lhe,ipartner_lhe
1728+ common/cto_LHE2/scale1_lhe,scale2_lhe
1729+c
1730+c forbid unweighting close to the fks pole (should not happen but better safe than sorry)
1731+ double precision p_i_fks_ev(0:3),p_i_fks_cnt(0:3,-2:2)
1732+ double precision xi_i_fks_ev,y_ij_fks_ev
1733+ common/fksvariables/xi_i_fks_ev,y_ij_fks_ev,p_i_fks_ev,p_i_fks_cnt
1734+c
1735+c Auxiliary quantities used when writing events
1736+ integer kwgtinfo
1737+ integer i_wgt, kk, ii, jj, n, nn
1738+ character*140 buff
1739+ INTEGER MAXNUP
1740+ PARAMETER (MAXNUP=500)
1741+ INTEGER NUP,IDPRUP,IDUP(MAXNUP),ISTUP(MAXNUP),
1742+ & MOTHUP(2,MAXNUP),ICOLUP(2,MAXNUP)
1743+ DOUBLE PRECISION XWGTUP,AQEDUP,AQCDUP,
1744+ & PUP(5,MAXNUP),VTIMUP(MAXNUP),SPINUP(MAXNUP)
1745+c maximum weight ratio for the partial unweighting
1746+ integer npoints
1747+ double precision cross_section
1748+ common /for_FixedOrder_lhe/ cross_section,npoints
1749+c --- do the partial unweighting (don't do it when to close to singular
1750+c --- region)
1751+ twgt=abs(cross_section)*FO_LHE_weight_ratio !/npoints
1752+ if(abs(wgts(1)).lt.abs(twgt) .and. xi_i_fks_ev.gt.1d-3 .and.
1753+ $ 1d0-y_ij_fks_ev.gt.1d-2)then
1754+ R = ran2()*abs(twgt)
1755+ if (R.gt.abs(wgts(1)))then
1756+ return
1757+ else
1758+ do i=2,nwgts
1759+ wgts(i) = wgts(i)*abs(twgt/wgts(1))
1760+ enddo
1761+ wgts(1) = sign(twgt,wgts(1))
1762+ endif
1763+ endif
1764+c --- accumulate the total weights of all the events in the event file
1765+ sum_of_wgts=sum_of_wgts+wgts(1)
1766+
1767+c --- fill the multi-weight common blocks with the scale and PDF
1768+c --- variation weights
1769+ i_wgt=1
1770+ if (do_rwgt_scale) then
1771+ do kk=1,dyn_scale(0)
1772+ if (lscalevar(kk)) then
1773+ do ii=1,nint(scalevarF(0))
1774+ do jj=1,nint(scalevarR(0))
1775+ i_wgt=i_wgt+1
1776+ wgtxsecmu(jj,ii,kk)= wgts(i_wgt)
1777+ enddo
1778+ enddo
1779+ else
1780+ i_wgt=i_wgt+1
1781+ wgtxsecmu(1,1,kk)= wgts(i_wgt)
1782+ endif
1783+ enddo
1784+ endif
1785+ if (do_rwgt_pdf) then
1786+ do nn=1,lhaPDFid(0)
1787+ if (lpdfvar(nn)) then
1788+ do n=0,nmemPDF(nn)
1789+ i_wgt=i_wgt+1
1790+ wgtxsecPDF(n,nn) = wgts(i_wgt)
1791+ enddo
1792+ else
1793+ i_wgt=i_wgt+1
1794+ wgtxsecPDF(0,nn) = wgts(i_wgt)
1795+ endif
1796+ enddo
1797+ endif
1798+
1799+c --- prepare the event file info according to the LesHouches standard
1800+ npart = nexternal
1801+ do i=1,nexternal
1802+ IDUP(i)= ipdg(i)
1803+ ISTUP(i)= istatus(i)
1804+ MOTHUP(1,i)=0
1805+ MOTHUP(2,i)=0
1806+ ICOLUP(1,i)=599
1807+ ICOLUP(2,i)=599
1808+ PUP(1,i)=p(1,i)
1809+ PUP(2,i)=p(2,i)
1810+ PUP(3,i)=p(3,i)
1811+ PUP(4,i)=p(0,i)
1812+ PUP(5,i)=p(4,i)
1813+ VTIMUP(i)=0.d0
1814+ SPINUP(i)=9
1815+ enddo
1816+
1817+c --- prepare the buffer information
1818+ if(.not.doreweight)then
1819+ write(buff,201)'#aMCatNLO',iSorH_lhe,ifks_lhe(nFKSprocess)
1820+ & ,jfks_lhe(nFKSprocess),fksfather_lhe(nFKSprocess)
1821+ & ,ipartner_lhe(nFKSprocess),scale1_lhe(nFKSprocess)
1822+ & ,scale2_lhe(nFKSprocess),izero,izero,izero,zero,zero
1823+ & ,zero,zero,ibody*1d0
1824+ else
1825+ if(iwgtinfo.ne.-5)then
1826+ write(*,*)'Error in write_events_lhe'
1827+ write(*,*)' Inconsistency in reweight parameters'
1828+ write(*,*)doreweight,iwgtinfo
1829+ stop
1830+ endif
1831+ kwgtinfo= 9
1832+ write(buff,201)'#aMCatNLO',iSorH_lhe,ifks_lhe(nFKSprocess)
1833+ & ,jfks_lhe(nFKSprocess),fksfather_lhe(nFKSprocess)
1834+ & ,ipartner_lhe(nFKSprocess),scale1_lhe(nFKSprocess)
1835+ & ,scale2_lhe(nFKSprocess),kwgtinfo,nexternal,iwgtnumpartn
1836+ & ,zero,zero,zero,zero,ibody*1d0
1837+ endif
1838+
1839+c --- write the event
1840+ call write_lhef_event(41,
1841+ & npart,IDPRUP,wgts(1),0d0,0d0,0d0,
1842+ & IDUP,ISTUP,MOTHUP,ICOLUP,PUP,VTIMUP,SPINUP,buff)
1843+
1844+ 201 format(a9,1x,i1,4(1x,i2),2(1x,d14.8),2x,i2,2(1x,i2),5(1x,d14.8))
1845+ end
1846+
1847+c This we can use for the event grouping!
1848+ subroutine HwU_add_points
1849+ implicit none
1850+ integer nwgts,nevents
1851+ double precision sum_of_wgts
1852+ common/to_lhe_analysis/sum_of_wgts,nwgts,nevents
1853+ nevents=nevents+1
1854+ write (41,'(a)') '</eventgroup>'
1855+ write (41,'(a)') '<eventgroup>'
1856+ end
1857+
1858+c Dummy routines
1859+ subroutine HwU_accum_iter(ldummy,idummy)
1860+ logical ldummy
1861+ integer idummy
1862+ end
1863+ subroutine HwU_output(idummy,dummy)
1864+ integer idummy
1865+ double precision dummy
1866+ write (*,*) 'HwU_output should not be called',idummy
1867+ stop 1
1868+ end
1869+ subroutine addfil(string)
1870+ character*(*) string
1871+ end
1872+ subroutine accum(ldummy)
1873+ logical ldummy
1874+ end
1875
1876=== modified file 'Template/NLO/SubProcesses/driver_mintFO.f'
1877--- Template/NLO/SubProcesses/driver_mintFO.f 2016-01-22 15:02:25 +0000
1878+++ Template/NLO/SubProcesses/driver_mintFO.f 2017-03-08 10:27:27 +0000
1879@@ -32,10 +32,6 @@
1880 include 'run.inc'
1881 include 'coupl.inc'
1882
1883- integer iconfig
1884- common/to_configs/iconfig
1885-
1886-
1887 double precision twgt, maxwgt,swgt(maxevents)
1888 integer lun, nw
1889 common/to_unwgt/twgt, maxwgt, swgt, lun, nw
1890@@ -59,9 +55,11 @@
1891 integer n_mp, n_disc
1892 c For MINT:
1893 include "mint.inc"
1894- real* 8 xgrid(0:nintervals,ndimmax),ymax(nintervals,ndimmax)
1895- $ ,ymax_virt,ans(nintegrals),unc(nintegrals),chi2(nintegrals)
1896- $ ,x(ndimmax),itmax_fl
1897+ integer nhits_in_grids(maxchannels)
1898+ real* 8 xgrid(0:nintervals,ndimmax,maxchannels),ymax(nintervals
1899+ $ ,ndimmax,maxchannels),ymax_virt(maxchannels),ans(nintegrals
1900+ $ ,0:maxchannels),unc(nintegrals,0:maxchannels),chi2(nintegrals
1901+ $ ,0:maxchannels),x(ndimmax),itmax_fl
1902 integer ixi_i,iphi_i,iy_ij,vn
1903 integer ifold(ndimmax)
1904 common /cifold/ifold
1905@@ -72,13 +70,6 @@
1906 logical unwgt
1907 double precision evtsgn
1908 common /c_unwgt/evtsgn,unwgt
1909- integer nvirt(nintervals_virt,ndimmax),nvirt_acc(nintervals_virt
1910- $ ,ndimmax)
1911- double precision ave_virt(nintervals_virt,ndimmax)
1912- $ ,ave_virt_acc(nintervals_virt,ndimmax)
1913- $ ,ave_born_acc(nintervals_virt ,ndimmax)
1914- common/c_ave_virt/ave_virt,ave_virt_acc,ave_born_acc,nvirt
1915- $ ,nvirt_acc
1916
1917 logical SHsep
1918 logical Hevents
1919@@ -90,7 +81,8 @@
1920
1921 double precision virtual_over_born
1922 common/c_vob/virtual_over_born
1923- double precision average_virtual,virtual_fraction
1924+ double precision average_virtual(maxchannels)
1925+ $ ,virtual_fraction(maxchannels)
1926 common/c_avg_virt/average_virtual,virtual_fraction
1927
1928 c timing statistics
1929@@ -121,8 +113,10 @@
1930 c Read general MadFKS parameters
1931 c
1932 call FKSParamReader(paramFileName,.TRUE.,.FALSE.)
1933- average_virtual=0d0
1934- virtual_fraction=max(virt_fraction,min_virt_fraction)
1935+ do kchan=1,maxchannels
1936+ average_virtual(kchan)=0d0
1937+ virtual_fraction(kchan)=max(virt_fraction,min_virt_fraction)
1938+ enddo
1939
1940
1941 c
1942@@ -164,7 +158,7 @@
1943 c Get user input
1944 c
1945 write(*,*) "getting user params"
1946- call get_user_params(ncall,itmax,iconfig,imode)
1947+ call get_user_params(ncall,itmax,imode)
1948 if(imode.eq.0)then
1949 flat_grid=.true.
1950 else
1951@@ -183,7 +177,7 @@
1952 write(*,*)'NLO computations require muF1=muF2'
1953 stop
1954 endif
1955- write(*,*) "about to integrate ", ndim,ncall,itmax,iconfig
1956+ write(*,*) "about to integrate ", ndim,ncall,itmax
1957 c APPLgrid
1958 if (imode.eq.0) iappl=0 ! overwrite when starting completely fresh
1959 if(iappl.ne.0) then
1960@@ -203,23 +197,27 @@
1961 if(imode.eq.0)then
1962 c Don't safe the reweight information when just setting up the grids.
1963 doreweight=.false.
1964- do j=0,nintervals
1965+ do kchan=1,nchans
1966 do i=1,ndimmax
1967- xgrid(j,i)=0.d0
1968+ do j=0,nintervals
1969+ xgrid(j,i,kchan)=0.d0
1970+ enddo
1971 enddo
1972 enddo
1973 else
1974 doreweight=do_rwgt_scale.or.do_rwgt_pdf
1975 c to restore grids:
1976 open (unit=12, file='mint_grids',status='old')
1977- do j=0,nintervals
1978- read (12,*) (xgrid(j,i),i=1,ndim)
1979- enddo
1980- do j=1,nintervals_virt
1981- read (12,*) (ave_virt(j,i),i=1,ndim)
1982- enddo
1983- read (12,*) ans(1),unc(1),dummy,dummy
1984- read (12,*) virtual_fraction,average_virtual
1985+ do kchan=1,nchans
1986+ do j=0,nintervals
1987+ read (12,*) (xgrid(j,i,kchan),i=1,ndim)
1988+ enddo
1989+ do j=1,nintervals_virt
1990+ read (12,*) (ave_virt(j,i,kchan),i=1,ndim)
1991+ enddo
1992+ read(12,*) ans(1,kchan),unc(1,kchan),dummy,dummy,nhits_in_grids(kchan)
1993+ read(12,*) virtual_fraction(kchan),average_virtual(kchan)
1994+ enddo
1995 close (12)
1996 write (*,*) "Update iterations and points to",itmax,ncall
1997 endif
1998@@ -228,31 +226,38 @@
1999
2000 if (ickkw.eq.-1) then
2001 min_virt_fraction=1d0
2002- virtual_fraction=1d0
2003+ do kchan=1,nchans
2004+ virtual_fraction(kchan)=1d0
2005+ enddo
2006 endif
2007 c
2008 c Setup for parton-level NLO reweighting
2009 if(do_rwgt_scale.or.do_rwgt_pdf) call setup_fill_rwgt_NLOplot()
2010- call mint(sigint,ndim,ncall,itmax,imode,xgrid,ymax,ymax_virt
2011- $ ,ans,unc,chi2)
2012+ call mint(sigint,ndim,ncall,itmax,imode,xgrid,ymax
2013+ $ ,ymax_virt,ans,unc,chi2,nhits_in_grids)
2014 call topout
2015- write(*,*)'Final result [ABS]:',ans(1),' +/-',unc(1)
2016- write(*,*)'Final result:',ans(2),' +/-',unc(2)
2017- write(*,*)'chi**2 per D.o.F.:',chi2(1)
2018+ write(*,*)'Final result [ABS]:',ans(1,0),' +/-',unc(1,0)
2019+ write(*,*)'Final result:',ans(2,0),' +/-',unc(2,0)
2020+ write(*,*)'chi**2 per D.o.F.:',chi2(1,0)
2021 open(unit=58,file='results.dat',status='unknown')
2022- write(58,*) ans(1),unc(2),0d0,0,0,0,0,0d0,0d0,ans(2)
2023+ do kchan=0,nchans
2024+ write(58,*) ans(1,kchan),unc(2,kchan),0d0,0,0,0,0,0d0,0d0
2025+ $ ,ans(2,kchan)
2026+ enddo
2027 close(58)
2028 c
2029 c to save grids:
2030 open (unit=12, file='mint_grids',status='unknown')
2031- do j=0,nintervals
2032- write (12,*) (xgrid(j,i),i=1,ndim)
2033- enddo
2034- do j=1,nintervals_virt
2035- write (12,*) (ave_virt(j,i),i=1,ndim)
2036- enddo
2037- write (12,*) ans(1),unc(1),ncall,itmax
2038- write (12,*) virtual_fraction,average_virtual
2039+ do kchan=1,nchans
2040+ do j=0,nintervals
2041+ write (12,*) (xgrid(j,i,kchan),i=1,ndim)
2042+ enddo
2043+ do j=1,nintervals_virt
2044+ write (12,*) (ave_virt(j,i,kchan),i=1,ndim)
2045+ enddo
2046+ write (12,*) ans(1,kchan),unc(1,kchan),ncall,itmax,nhits_in_grids(kchan)
2047+ write (12,*) virtual_fraction(kchan),average_virtual(kchan)
2048+ enddo
2049 close (12)
2050 else
2051 write (*,*) 'Unknown imode',imode
2052@@ -317,7 +322,10 @@
2053 write(*,*) 'Time spent in Total : ',tTot
2054
2055 open (unit=12, file='res.dat',status='unknown')
2056- write (12,*)ans(1),unc(1),ans(2),unc(2),itmax,ncall,tTot
2057+ do kchan=0,nchans
2058+ write (12,*)ans(1,kchan),unc(1,kchan),ans(2,kchan),unc(2,kchan)
2059+ $ ,itmax,ncall,tTot
2060+ enddo
2061 close(12)
2062
2063
2064@@ -378,8 +386,6 @@
2065 common/tosigint/ndim
2066 logical nbody
2067 common/cnbody/nbody
2068- integer iconfig
2069- common/to_configs/iconfig
2070 double precision p1_cnt(0:3,nexternal,-2:2),wgt_cnt(-2:2)
2071 $ ,pswgt_cnt(-2:2),jac_cnt(-2:2)
2072 common/counterevnts/p1_cnt,wgt_cnt,pswgt_cnt,jac_cnt
2073@@ -612,7 +618,7 @@
2074 end
2075
2076 c
2077- subroutine get_user_params(ncall,itmax,iconfig,irestart)
2078+ subroutine get_user_params(ncall,itmax,irestart)
2079 c**********************************************************************
2080 c Routine to get user specified parameters for run
2081 c**********************************************************************
2082@@ -625,23 +631,22 @@
2083 include 'nFKSconfigs.inc'
2084 include 'fks_info.inc'
2085 include 'run.inc'
2086+ include 'mint.inc'
2087 c
2088 c Arguments
2089 c
2090- integer ncall,itmax,iconfig, jconfig
2091+ integer ncall,itmax
2092 c
2093 c Local
2094 c
2095 integer i, j
2096- double precision dconfig
2097+ double precision dconfig(maxchannels)
2098 c
2099 c Global
2100 c
2101 integer isum_hel
2102 logical multi_channel
2103 common/to_matrix/isum_hel, multi_channel
2104- double precision accuracy
2105- common /to_accuracy/accuracy
2106 integer use_cut
2107 common /to_weight/use_cut
2108
2109@@ -679,9 +684,10 @@
2110 integer mc_hel,ihel
2111 double precision volh
2112 common/mc_int2/volh,mc_hel,ihel,fillh
2113-
2114+ integer random_offset_split
2115+ common /c_random_offset_split/ random_offset_split
2116 logical done
2117- character*100 buffer
2118+ character*140 buffer
2119 c-----
2120 c Begin Code
2121 c-----
2122@@ -689,6 +695,7 @@
2123 unwgt=.false.
2124 open (unit=83,file='input_app.txt',status='old')
2125 done=.false.
2126+ nchans=0
2127 do while (.not. done)
2128 read(83,'(a)',err=222,end=222) buffer
2129 if (buffer(1:7).eq.'NPOINTS') then
2130@@ -728,19 +735,40 @@
2131 write(*,*) 'Do MC over helicities for the virtuals'
2132 endif
2133 isum_hel=0
2134+ elseif(buffer(1:6).eq.'NCHANS') then
2135+ read(buffer(9:),*) nchans
2136+ write (*,*) 'Number of channels to integrate together:'
2137+ $ ,nchans
2138+ if (nchans.gt.maxchannels) then
2139+ write (*,*) 'Too many integration channels to be '/
2140+ $ /'integrated together. Increase maxchannels',nchans
2141+ $ ,maxchannels
2142+ stop 1
2143+ endif
2144 elseif(buffer(1:7).eq.'CHANNEL') then
2145- read(buffer(10:),*) dconfig
2146- iconfig = int(dconfig)
2147- do i=1,mapconfig(0)
2148- if (iconfig.eq.mapconfig(i)) then
2149- iconfig=i
2150- exit
2151- endif
2152+ if (nchans.le.0) then
2153+ write (*,*) '"NCHANS" missing in input files'/
2154+ $ /' (still zero)',nchans
2155+ stop
2156+ endif
2157+ read(buffer(10:),*) (dconfig(kchan),kchan=1,nchans)
2158+ do kchan=1,nchans
2159+ iconfigs(kchan) = int(dconfig(kchan))
2160+ do i=1,mapconfig(0)
2161+ if (iconfigs(kchan).eq.mapconfig(i)) then
2162+ iconfigs(kchan)=i
2163+ exit
2164+ endif
2165+ enddo
2166 enddo
2167- write(*,12) 'Running Configuration Number: ',iconfig
2168+ write(*,*) 'Running Configuration Number(s): '
2169+ $ ,(iconfigs(kchan),kchan=1,nchans)
2170 elseif(buffer(1:5).eq.'SPLIT') then
2171- read(buffer(8:),*) i
2172- write (*,*) 'Splitting channel:',i
2173+ read(buffer(8:),*) random_offset_split
2174+ write (*,*) 'Splitting channel:',random_offset_split
2175+ elseif(buffer(1:8).eq.'WGT_MULT') then
2176+ read(buffer(11:),*) wgt_mult
2177+ write (*,*) 'Weight multiplier:',wgt_mult
2178 elseif(buffer(1:8).eq.'RUN_MODE') then
2179 read(buffer(11:),*) abrvinput
2180 if(abrvinput(5:5).eq.'0')then
2181@@ -785,20 +813,9 @@
2182 endif
2183 endif
2184 c
2185-c
2186 c Here I want to set up with B.W. we map and which we don't
2187 c
2188- dconfig = dconfig-iconfig
2189- if (dconfig .eq. 0) then
2190- write(*,*) 'Not subdividing B.W.'
2191- lbw(0)=0
2192- else
2193- lbw(0)=1
2194- jconfig=dconfig*1000.1
2195- write(*,*) 'Using dconfig=',jconfig
2196- call DeCode(jconfig,lbw(1),3,nexternal)
2197- write(*,*) 'BW Setting ', (lbw(j),j=1,nexternal-2)
2198- endif
2199+ lbw(0)=0
2200 10 format( a)
2201 12 format( a,i4)
2202 end
2203
2204=== modified file 'Template/NLO/SubProcesses/driver_mintMC.f'
2205--- Template/NLO/SubProcesses/driver_mintMC.f 2016-01-22 15:02:25 +0000
2206+++ Template/NLO/SubProcesses/driver_mintMC.f 2017-03-08 10:27:27 +0000
2207@@ -30,10 +30,8 @@
2208 cc
2209 include 'run.inc'
2210 include 'coupl.inc'
2211+ include "mint.inc"
2212
2213- integer iconfig
2214- common/to_configs/iconfig
2215-
2216 c Vegas stuff
2217 common/tosigint/ndim
2218
2219@@ -49,16 +47,16 @@
2220
2221 double precision virtual_over_born
2222 common/c_vob/virtual_over_born
2223- double precision average_virtual,virtual_fraction
2224+ double precision average_virtual(maxchannels),virtual_fraction(maxchannels)
2225 common/c_avg_virt/average_virtual,virtual_fraction
2226
2227 double precision weight
2228 c For MINT:
2229- include "mint.inc"
2230- real* 8 xgrid(0:nintervals,ndimmax),ymax(nintervals,ndimmax)
2231- $ ,ymax_virt,ans(nintegrals),unc(nintegrals),chi2(nintegrals)
2232- $ ,x(ndimmax)
2233- integer ixi_i,iphi_i,iy_ij,vn
2234+ real* 8 xgrid(0:nintervals,ndimmax,maxchannels),ymax(nintervals
2235+ $ ,ndimmax,maxchannels),ymax_virt(maxchannels),ans(nintegrals
2236+ $ ,0:maxchannels),unc(nintegrals,0:maxchannels),chi2(nintegrals
2237+ $ ,0:maxchannels),x(ndimmax)
2238+ integer ixi_i,iphi_i,iy_ij,vn,nhits_in_grids(maxchannels)
2239 integer ifold(ndimmax)
2240 common /cifold/ifold
2241 integer ifold_energy,ifold_phi,ifold_yij
2242@@ -70,13 +68,6 @@
2243 logical unwgt
2244 double precision evtsgn
2245 common /c_unwgt/evtsgn,unwgt
2246- integer nvirt(nintervals_virt,ndimmax),nvirt_acc(nintervals_virt
2247- $ ,ndimmax)
2248- double precision ave_virt(nintervals_virt,ndimmax)
2249- $ ,ave_virt_acc(nintervals_virt,ndimmax)
2250- $ ,ave_born_acc(nintervals_virt ,ndimmax)
2251- common/c_ave_virt/ave_virt,ave_virt_acc,ave_born_acc,nvirt
2252- $ ,nvirt_acc
2253 double precision ran2
2254 external ran2
2255
2256@@ -118,7 +109,7 @@
2257 c
2258 call FKSParamReader(paramFileName,.TRUE.,.FALSE.)
2259 average_virtual=0d0
2260- virtual_fraction=virt_fraction
2261+ virtual_fraction(1)=virt_fraction
2262
2263 ntot=0
2264 nsun=0
2265@@ -144,7 +135,7 @@
2266 c Get user input
2267 c
2268 write(*,*) "getting user params"
2269- call get_user_params(ncall,itmax,iconfig,imode,
2270+ call get_user_params(ncall,itmax,imode,
2271 & ixi_i,iphi_i,iy_ij,SHsep)
2272 c Only do the reweighting when actually generating the events
2273 if (imode.eq.2) then
2274@@ -189,49 +180,49 @@
2275 c initialize grids
2276 do j=0,nintervals
2277 do i=1,ndimmax
2278- xgrid(j,i)=0.d0
2279+ xgrid(j,i,1)=0.d0
2280 enddo
2281 enddo
2282 else
2283 c to restore grids:
2284 open (unit=12, file='mint_grids',status='old')
2285 do j=0,nintervals
2286- read (12,*) (xgrid(j,i),i=1,ndim)
2287+ read (12,*) (xgrid(j,i,1),i=1,ndim)
2288 enddo
2289 do j=1,nintervals_virt
2290- read (12,*) (ave_virt(j,i),i=1,ndim)
2291+ read (12,*) (ave_virt(j,i,1),i=1,ndim)
2292 enddo
2293- read (12,*) (ans(i),i=1,nintegrals)
2294+ read (12,*) (ans(i,1),i=1,nintegrals)
2295 read (12,*) ifold_energy,ifold_phi,ifold_yij
2296- read (12,*) virtual_fraction,average_virtual
2297+ read (12,*) virtual_fraction(1),average_virtual(1)
2298 close (12)
2299 endif
2300 c
2301 write (*,*) 'imode is ',imode
2302 call mint(sigintF,ndim,ncall,itmax,imode,xgrid,ymax,ymax_virt
2303- $ ,ans,unc,chi2)
2304+ $ ,ans,unc,chi2,nhits_in_grids)
2305 open(unit=58,file='res_0',status='unknown')
2306- write(58,*)'Final result [ABS]:',ans(1),' +/-',unc(1)
2307- write(58,*)'Final result:',ans(2),' +/-',unc(2)
2308+ write(58,*)'Final result [ABS]:',ans(1,1),' +/-',unc(1,1)
2309+ write(58,*)'Final result:',ans(2,1),' +/-',unc(2,1)
2310 close(58)
2311- write(*,*)'Final result [ABS]:',ans(1),' +/-',unc(1)
2312- write(*,*)'Final result:',ans(2),' +/-',unc(2)
2313- write(*,*)'chi**2 per D.o.F.:',chi2(1)
2314+ write(*,*)'Final result [ABS]:',ans(1,1),' +/-',unc(1,1)
2315+ write(*,*)'Final result:',ans(2,1),' +/-',unc(2,1)
2316+ write(*,*)'chi**2 per D.o.F.:',chi2(1,1)
2317 open(unit=58,file='results.dat',status='unknown')
2318- write(58,*) ans(1),unc(2),0d0,0,0,0,0,0d0,0d0,ans(2)
2319+ write(58,*) ans(1,1),unc(2,1),0d0,0,0,0,0,0d0,0d0,ans(2,1)
2320 close(58)
2321 c
2322 c to save grids:
2323 open (unit=12, file='mint_grids',status='unknown')
2324 do j=0,nintervals
2325- write (12,*) (xgrid(j,i),i=1,ndim)
2326+ write (12,*) (xgrid(j,i,1),i=1,ndim)
2327 enddo
2328 do j=1,nintervals_virt
2329- write (12,*) (ave_virt(j,i),i=1,ndim)
2330+ write (12,*) (ave_virt(j,i,1),i=1,ndim)
2331 enddo
2332- write (12,*) (ans(i),i=1,nintegrals)
2333+ write (12,*) (ans(i,1),i=1,nintegrals)
2334 write (12,*) ifold_energy,ifold_phi,ifold_yij
2335- write (12,*) virtual_fraction,average_virtual
2336+ write (12,*) virtual_fraction(1),average_virtual(1)
2337 close (12)
2338
2339 c*************************************************************
2340@@ -241,14 +232,14 @@
2341 c to restore grids:
2342 open (unit=12, file='mint_grids',status='old')
2343 do j=0,nintervals
2344- read (12,*) (xgrid(j,i),i=1,ndim)
2345+ read (12,*) (xgrid(j,i,1),i=1,ndim)
2346 enddo
2347 do j=1,nintervals_virt
2348- read (12,*) (ave_virt(j,i),i=1,ndim)
2349+ read (12,*) (ave_virt(j,i,1),i=1,ndim)
2350 enddo
2351- read (12,*) (ans(i),i=1,nintegrals)
2352+ read (12,*) (ans(i,1),i=1,nintegrals)
2353 read (12,*) ifold_energy,ifold_phi,ifold_yij
2354- read (12,*) virtual_fraction,average_virtual
2355+ read (12,*) virtual_fraction(1),average_virtual(1)
2356 close (12)
2357
2358 c Prepare the MINT folding
2359@@ -265,45 +256,45 @@
2360
2361 write (*,*) 'imode is ',imode
2362 call mint(sigintF,ndim,ncall,itmax,imode,xgrid,ymax,ymax_virt
2363- $ ,ans,unc,chi2)
2364+ $ ,ans,unc,chi2,nhits_in_grids)
2365
2366 c If integrating the virtuals alone, we include the virtuals in
2367 c ans(1). Therefore, no need to have them in ans(5) and we have to set
2368 c them to zero.
2369 if (only_virt) then
2370- ans(3)=0d0 ! virtual Xsec
2371- ans(5)=0d0 ! ABS virtual Xsec
2372+ ans(3,1)=0d0 ! virtual Xsec
2373+ ans(5,1)=0d0 ! ABS virtual Xsec
2374 endif
2375
2376 open(unit=58,file='res_1',status='unknown')
2377- write(58,*)'Final result [ABS]:',ans(1)+ans(5),' +/-'
2378- $ ,sqrt(unc(1)**2+unc(5)**2)
2379- write(58,*)'Final result:',ans(2),' +/-',unc(2)
2380+ write(58,*)'Final result [ABS]:',ans(1,1)+ans(5,1),' +/-'
2381+ $ ,sqrt(unc(1,1)**2+unc(5,1)**2)
2382+ write(58,*)'Final result:',ans(2,1),' +/-',unc(2,1)
2383 close(58)
2384- write(*,*)'Final result [ABS]:',ans(1)+ans(5),' +/-'
2385- $ ,sqrt(unc(1)**2+unc(5)**2)
2386- write(*,*)'Final result:',ans(2),' +/-',unc(2)
2387- write(*,*)'chi**2 per D.o.F.:',chi2(1)
2388+ write(*,*)'Final result [ABS]:',ans(1,1)+ans(5,1),' +/-'
2389+ $ ,sqrt(unc(1,1)**2+unc(5,1)**2)
2390+ write(*,*)'Final result:',ans(2,1),' +/-',unc(2,1)
2391+ write(*,*)'chi**2 per D.o.F.:',chi2(1,1)
2392 c write the results.dat file
2393 open(unit=58,file='results.dat',status='unknown')
2394- write(58,*)ans(1)+ans(5), unc(2), 0d0, 0, 0, 0, 0, 0d0 ,0d0, ans(2)
2395+ write(58,*)ans(1,1)+ans(5,1), unc(2,1), 0d0, 0, 0, 0, 0, 0d0 ,0d0, ans(2,1)
2396 close(58)
2397
2398 c to save grids:
2399 open (unit=12, file='mint_grids',status='unknown')
2400- write (12,*) (xgrid(0,i),i=1,ndim)
2401+ write (12,*) (xgrid(0,i,1),i=1,ndim)
2402 do j=1,nintervals
2403- write (12,*) (xgrid(j,i),i=1,ndim)
2404- write (12,*) (ymax(j,i),i=1,ndim)
2405+ write (12,*) (xgrid(j,i,1),i=1,ndim)
2406+ write (12,*) (ymax(j,i,1),i=1,ndim)
2407 enddo
2408 do j=1,nintervals_virt
2409- write (12,*) (ave_virt(j,i),i=1,ndim)
2410+ write (12,*) (ave_virt(j,i,1),i=1,ndim)
2411 enddo
2412- write (12,*) ymax_virt
2413+ write (12,*) ymax_virt(1)
2414 write (12,*) (ifold(i),i=1,ndim)
2415- write (12,*) (ans(i),i=1,nintegrals)
2416- write (12,*) (unc(i),i=1,nintegrals)
2417- write (12,*) virtual_fraction,average_virtual
2418+ write (12,*) (ans(i,1),i=1,nintegrals)
2419+ write (12,*) (unc(i,1),i=1,nintegrals)
2420+ write (12,*) virtual_fraction(1),average_virtual(1)
2421 close (12)
2422
2423 c*************************************************************
2424@@ -328,23 +319,23 @@
2425
2426 c to restore grids:
2427 open (unit=12, file='mint_grids',status='unknown')
2428- read (12,*) (xgrid(0,i),i=1,ndim)
2429+ read (12,*) (xgrid(0,i,1),i=1,ndim)
2430 do j=1,nintervals
2431- read (12,*) (xgrid(j,i),i=1,ndim)
2432- read (12,*) (ymax(j,i),i=1,ndim)
2433+ read (12,*) (xgrid(j,i,1),i=1,ndim)
2434+ read (12,*) (ymax(j,i,1),i=1,ndim)
2435 enddo
2436 do j=1,nintervals_virt
2437- read (12,*) (ave_virt(j,i),i=1,ndim)
2438+ read (12,*) (ave_virt(j,i,1),i=1,ndim)
2439 enddo
2440- read (12,*) ymax_virt
2441+ read (12,*) ymax_virt(1)
2442 read (12,*) (ifold(i),i=1,ndim)
2443- read (12,*) (ans(i),i=1,nintegrals)
2444- read (12,*) (unc(i),i=1,nintegrals)
2445- read (12,*) virtual_fraction,average_virtual
2446+ read (12,*) (ans(i,1),i=1,nintegrals)
2447+ read (12,*) (unc(i,1),i=1,nintegrals)
2448+ read (12,*) virtual_fraction(1),average_virtual(1)
2449 close (12)
2450
2451 c determine how many events for the virtual and how many for the no-virt
2452- ncall_virt=int(ans(5)/(ans(1)+ans(5)) * ncall)
2453+ ncall_virt=int(ans(5,1)/(ans(1,1)+ans(5,1)) * ncall)
2454 ncall_novi=ncall-ncall_virt
2455
2456 write (*,*) "Generating virt :: novi approx.",ncall_virt
2457@@ -355,11 +346,11 @@
2458 c fill the information for the write_header_init common block
2459 ifile=lunlhe
2460 ievents=ncall
2461- inter=ans(2)
2462- absint=ans(1)+ans(5)
2463- uncer=unc(2)
2464+ inter=ans(2,1)
2465+ absint=ans(1,1)+ans(5,1)
2466+ uncer=unc(2,1)
2467
2468- weight=(ans(1)+ans(5))/ncall
2469+ weight=(ans(1,1)+ans(5,1))/ncall
2470
2471 if (abrv(1:3).ne.'all' .and. abrv(1:4).ne.'born' .and.
2472 $ abrv(1:4).ne.'virt') then
2473@@ -375,7 +366,7 @@
2474 vn=3
2475 call gen(sigintF,ndim,xgrid,ymax,ymax_virt,1,x,vn)
2476 else
2477- if (ran2().lt.ans(5)/(ans(1)+ans(5)) .or. only_virt) then
2478+ if (ran2().lt.ans(5,1)/(ans(1,1)+ans(5,1)) .or. only_virt) then
2479 abrv='virt'
2480 if (only_virt) then
2481 vn=2
2482@@ -474,10 +465,10 @@
2483
2484 open (unit=12, file='res.dat',status='unknown')
2485 if (imode.eq.0) then
2486- write (12,*)ans(1),unc(1),ans(2),unc(2),itmax,ncall,tTot
2487+ write (12,*)ans(1,1),unc(1,1),ans(2,1),unc(2,1),itmax,ncall,tTot
2488 else
2489- write (12,*)ans(1)+ans(5),sqrt(unc(1)**2+unc(5)**2),ans(2)
2490- $ ,unc(2),itmax,ncall,tTot
2491+ write (12,*)ans(1,1)+ans(5,1),sqrt(unc(1,1)**2+unc(5,1)**2),ans(2,1)
2492+ $ ,unc(2,1),itmax,ncall,tTot
2493 endif
2494 close(12)
2495
2496@@ -515,7 +506,7 @@
2497 end
2498
2499
2500- subroutine get_user_params(ncall,itmax,iconfig,
2501+ subroutine get_user_params(ncall,itmax,
2502 & imode,ixi_i,iphi_i,iy_ij,SHsep)
2503 c**********************************************************************
2504 c Routine to get user specified parameters for run
2505@@ -533,7 +524,7 @@
2506 c
2507 c Arguments
2508 c
2509- integer ncall,itmax,iconfig, jconfig
2510+ integer ncall,itmax,jconfig
2511 c
2512 c Local
2513 c
2514@@ -667,6 +658,9 @@
2515 endif
2516 enddo
2517 write(*,12) 'Running Configuration Number: ',iconfig
2518+ nchans=1
2519+ iconfigs(1)=iconfig
2520+ wgt_mult=1d0
2521
2522 write (*,'(a)') 'Enter running mode for MINT:'
2523 write (*,'(a)') '0 to set-up grids, 1 to integrate,'//
2524@@ -766,8 +760,6 @@
2525 external passcuts
2526 parameter (izero=0,ione=1,itwo=2,mohdr=-100)
2527 data firsttime/.true./
2528- integer iconfig
2529- common/to_configs/iconfig
2530 double precision p_born(0:3,nexternal-1)
2531 common /pborn/ p_born
2532 integer fold
2533
2534=== modified file 'Template/NLO/SubProcesses/fks_singular.f'
2535--- Template/NLO/SubProcesses/fks_singular.f 2016-10-12 13:52:46 +0000
2536+++ Template/NLO/SubProcesses/fks_singular.f 2017-03-08 10:27:27 +0000
2537@@ -4404,6 +4404,7 @@
2538 include "run.inc"
2539 include "fks_powers.inc"
2540 include 'reweight.inc'
2541+ include "mint.inc"
2542 double precision p(0:3,nexternal),bsv_wgt,born_wgt,avv_wgt
2543 double precision pp(0:3,nexternal)
2544
2545@@ -4460,7 +4461,7 @@
2546 integer iminmax
2547 common/cExceptPSpoint/iminmax,ExceptPSpoint
2548
2549- double precision average_virtual,virtual_fraction
2550+ double precision average_virtual(maxchannels),virtual_fraction(maxchannels)
2551 common/c_avg_virt/average_virtual,virtual_fraction
2552 double precision virtual_over_born
2553 common/c_vob/virtual_over_born
2554@@ -4635,7 +4636,7 @@
2555 c convert to Binoth Les Houches Accord standards
2556 virt_wgt=0d0
2557 if (fold.eq.0) then
2558- if ((ran2().le.virtual_fraction .and.
2559+ if ((ran2().le.virtual_fraction(ichan) .and.
2560 $ abrv(1:3).ne.'nov').or.abrv(1:4).eq.'virt') then
2561 call cpu_time(tBefore)
2562 Call BinothLHA(p_born,born_wgt,virt_wgt)
2563@@ -4644,9 +4645,9 @@
2564 tOLP=tOLP+(tAfter-tBefore)
2565 virtual_over_born=virt_wgt/(born_wgt*ao2pi)
2566 if (ickkw.ne.-1)
2567- & virt_wgt=virt_wgt-average_virtual*born_wgt*ao2pi
2568+ & virt_wgt=virt_wgt-average_virtual(ichan)*born_wgt*ao2pi
2569 if (abrv.ne.'virt') then
2570- virt_wgt=virt_wgt/virtual_fraction
2571+ virt_wgt=virt_wgt/virtual_fraction(ichan)
2572 endif
2573 virt_wgt_save=virt_wgt
2574 c$$$ bsv_wgt=bsv_wgt+virt_wgt_save
2575@@ -4656,7 +4657,7 @@
2576 c$$$ bsv_wgt=bsv_wgt+virt_wgt_save
2577 endif
2578 if (abrv(1:4).ne.'virt' .and. ickkw.ne.-1)
2579- & avv_wgt=average_virtual*born_wgt*ao2pi
2580+ & avv_wgt=average_virtual(ichan)*born_wgt*ao2pi
2581
2582 c eq.(MadFKS.C.13)
2583 if(abrv.eq.'viSA'.or.abrv.eq.'viSB')then
2584@@ -5415,9 +5416,11 @@
2585 end
2586
2587
2588- subroutine setfksfactor(iconfig,match_to_shower)
2589+ subroutine setfksfactor(match_to_shower)
2590 implicit none
2591
2592+ include 'mint.inc'
2593+
2594 double precision CA,CF, PI
2595 parameter (CA=3d0,CF=4d0/3d0)
2596 parameter (pi=3.1415926535897932385d0)
2597@@ -5431,7 +5434,7 @@
2598 logical softtest,colltest
2599 common/sctests/softtest,colltest
2600
2601- integer config_fks,i,j,iconfig,fac1,fac2
2602+ integer config_fks,i,j,fac1,fac2
2603 logical match_to_shower
2604
2605 double precision fkssymmetryfactor,fkssymmetryfactorBorn,
2606@@ -5474,6 +5477,8 @@
2607 common /cxiScut_used/xiScut_used,xiBSVcut_used
2608 logical rotategranny
2609 common/crotategranny/rotategranny
2610+ double precision diagramsymmetryfactor_save(maxchannels)
2611+ save diagramsymmetryfactor_save
2612 double precision diagramsymmetryfactor
2613 common /dsymfactor/diagramsymmetryfactor
2614
2615@@ -5715,6 +5720,7 @@
2616 c 'FKS_EW' STUFF
2617 iden_comp=dble(iden_born_FKS(nFKSprocess))/
2618 & dble(iden_real_FKS(nFKSprocess))
2619+
2620
2621
2622 c Set matrices used by MC counterterms
2623@@ -5749,27 +5755,35 @@
2624
2625 if (firsttime) then
2626 c Check to see if this channel needs to be included in the multi-channeling
2627- diagramsymmetryfactor=0d0
2628+ do kchan=1,nchans
2629+ diagramsymmetryfactor_save(kchan)=0d0
2630+ enddo
2631 if (multi_channel) then
2632 open (unit=19,file="symfact.dat",status="old",err=14)
2633 do i=1,mapconfig(0)
2634 read (19,*,err=23) fac1,fac2
2635- if (i.eq.iconfig) then
2636- if (mapconfig(iconfig).ne.fac1) then
2637- write (*,*) 'inconsistency in symfact.dat',i
2638- $ ,iconfig,mapconfig(iconfig),fac1
2639- stop
2640+ do kchan=1,nchans
2641+ if (i.eq.iconfigs(kchan)) then
2642+ if (mapconfig(iconfigs(kchan)).ne.fac1) then
2643+ write (*,*) 'inconsistency in symfact.dat',i
2644+ $ ,kchan,iconfigs(kchan)
2645+ $ ,mapconfig(iconfigs(kchan)),fac1
2646+ stop
2647+ endif
2648+ diagramsymmetryfactor_save(kchan)=dble(fac2)
2649 endif
2650- diagramsymmetryfactor=dble(fac2)
2651- endif
2652+ enddo
2653 enddo
2654 close(19)
2655 else ! no multi_channel
2656- diagramsymmetryfactor=1d0
2657+ do kchan=1,nchans
2658+ diagramsymmetryfactor_save(kchan)=1d0
2659+ enddo
2660 endif
2661 12 continue
2662 firsttime=.false.
2663 endif
2664+ diagramsymmetryfactor=diagramsymmetryfactor_save(ichan)
2665
2666 return
2667
2668@@ -5781,7 +5795,9 @@
2669 write (*,*) '"symfact.dat" is not of the correct format'
2670 stop
2671 14 continue
2672- diagramsymmetryfactor=1d0
2673+ do kchan=1,nchans
2674+ diagramsymmetryfactor_save(kchan)=1d0
2675+ enddo
2676 goto 12
2677 end
2678
2679
2680=== modified file 'Template/NLO/SubProcesses/madfks_plot.f'
2681--- Template/NLO/SubProcesses/madfks_plot.f 2016-11-23 21:35:25 +0000
2682+++ Template/NLO/SubProcesses/madfks_plot.f 2017-03-08 10:27:27 +0000
2683@@ -236,14 +236,9 @@
2684 integer istatus(nexternal),iPDG(nexternal)
2685 double precision pmass(nexternal)
2686 common/to_mass/pmass
2687- integer maxflow
2688- parameter (maxflow=999)
2689- integer idup(nexternal,maxproc),mothup(2,nexternal,maxproc),
2690- & icolup(2,nexternal,maxflow),niprocs
2691- common /c_leshouche_inc/idup,mothup,icolup,niprocs
2692- integer nwgt,max_weight
2693+ integer max_weight
2694 parameter (max_weight=maxscales*maxscales+maxpdfs+1)
2695- double precision www(max_weight),wgtden,ratio
2696+ double precision www(max_weight)
2697 double precision xsecScale_acc(maxscales,maxscales,maxdynscales)
2698 $ ,xsecPDFr_acc(0:maxPDFs,maxPDFsets)
2699 common /scale_pdf_print/xsecScale_acc,xsecPDFr_acc
2700@@ -265,7 +260,7 @@
2701 chybst=cosh(ybst_til_tolab)
2702 shybst=sinh(ybst_til_tolab)
2703 chybstmo=chybst-1.d0
2704- do i=nincoming+1,nexternal
2705+ do i=1,nexternal
2706 call boostwdir2(chybst,shybst,chybstmo,xd,pp(0,i),pplab(0,i))
2707 enddo
2708 c Fill the arrays (momenta, status and PDG):
2709
2710=== modified file 'Template/NLO/SubProcesses/mint-integrator2.f'
2711--- Template/NLO/SubProcesses/mint-integrator2.f 2016-09-27 15:07:53 +0000
2712+++ Template/NLO/SubProcesses/mint-integrator2.f 2017-03-08 10:27:27 +0000
2713@@ -63,7 +63,7 @@
2714 c nintegrals=6 : born*alpha_S/2Pi
2715 c
2716 subroutine mint(fun,ndim,ncalls0,nitmax,imode,xgrid,ymax,ymax_virt
2717- $ ,ans,unc,chi2)
2718+ $ ,ans,unc,chi2,nhits_in_grids)
2719 c imode= 0: integrate and adapt the grid
2720 c imode= 1: frozen grid, compute the integral and the upper bounds
2721 c imode=-1: same as imode=0, but use previously generated grids
2722@@ -72,28 +72,33 @@
2723 include "mint.inc"
2724 include "FKSParams.inc"
2725 integer i,j,ncalls0,ndim,nitmax,imode
2726- real * 8 fun,xgrid(0:nintervals,ndimmax),xint,ymax(nintervals
2727- $ ,ndimmax),ans(nintegrals),unc(nintegrals),ans3(nintegrals,3)
2728- $ ,unc3(nintegrals,3),ans_l3(nintegrals),unc_l3(nintegrals)
2729- $ ,chi2_l3(nintegrals)
2730- real * 8 xint_virt,ymax_virt
2731+ real * 8 fun,xgrid(0:nintervals,ndimmax,maxchannels)
2732+ $ ,xint(maxchannels),ymax(nintervals,ndimmax,maxchannels)
2733+ $ ,ans(nintegrals,0:maxchannels),unc(nintegrals,0:maxchannels)
2734+ $ ,ans3(nintegrals,3),unc3(nintegrals,3),ans_l3(nintegrals)
2735+ $ ,unc_l3(nintegrals),chi2_l3(nintegrals),vol_chan
2736+ real * 8 xint_virt(maxchannels),ymax_virt(maxchannels)
2737+ $ ,ans_chan(0:maxchannels)
2738 real * 8 x(ndimmax),vol
2739- real * 8 xacc(0:nintervals,ndimmax)
2740+ real * 8 xacc(0:nintervals,ndimmax,maxchannels)
2741 integer icell(ndimmax),ncell(ndimmax),ncell_virt
2742 integer ifold(ndimmax),kfold(ndimmax)
2743 common/cifold/ifold
2744- integer nhits(nintervals,ndimmax)
2745- real * 8 rand(ndimmax)
2746- real * 8 dx(ndimmax),f(nintegrals),vtot(nintegrals)
2747- $ ,etot(nintegrals),prod,f1(nintegrals),chi2(nintegrals)
2748- $ ,efrac(nintegrals),dummy
2749+ integer nhits(nintervals,ndimmax,maxchannels)
2750+ $ ,nhits_in_grids(maxchannels)
2751+ real * 8 rand(ndimmax),HwU_values(2)
2752+ real * 8 dx(ndimmax),f(nintegrals),vtot(nintegrals,0:maxchannels)
2753+ $ ,etot(nintegrals,0:maxchannels),prod,f1(nintegrals)
2754+ $ ,chi2(nintegrals,0:maxchannels),efrac(nintegrals),dummy
2755 integer kdim,kint,kpoint,nit,ncalls,iret,nintcurr,nintcurr_virt
2756 $ ,ifirst,nit_included,kpoint_iter,non_zero_point(nintegrals)
2757- $ ,ntotcalls(nintegrals),nint_used,nint_used_virt,min_it
2758+ $ ,ntotcalls(nintegrals),nint_used,nint_used_virt,min_it,np
2759 real * 8 ran3
2760 external ran3,fun
2761- logical even,double_events,bad_iteration
2762- double precision average_virtual,virtual_fraction
2763+ logical even,double_events,bad_iteration,regridded(maxchannels)
2764+ $ ,reset
2765+ double precision average_virtual(maxchannels)
2766+ $ ,virtual_fraction(maxchannels)
2767 common/c_avg_virt/average_virtual,virtual_fraction
2768 character*13 title(nintegrals)
2769 logical new_point
2770@@ -109,6 +114,11 @@
2771 common /for_applgrid/ iappl
2772 logical fixed_order,nlo_ps
2773 common /c_fnlo_nlops/fixed_order,nlo_ps
2774+ integer npoints
2775+ double precision cross_section
2776+ common /for_FixedOrder_lhe/ cross_section,npoints
2777+ reset=.false.
2778+
2779 c if ncalls0 is greater than 0, use the default running, i.e. do not
2780 c double the events after each iteration as well as use a fixed number
2781 c of intervals in the grids.
2782@@ -118,7 +128,7 @@
2783 nint_used_virt=nintervals_virt
2784 else
2785 c if ncalls0.le.0, reset it and double the events per iteration
2786- ncalls0=80*ndim
2787+ ncalls0=80*ndim*(nchans/3+1)
2788 double_events=.true.
2789 if (imode.eq.1 .or. imode.eq.-1) then
2790 nint_used=nintervals
2791@@ -139,21 +149,46 @@
2792 do kdim=1,ndim
2793 ifold(kdim)=1
2794 enddo
2795+ ans_chan(0)=0d0
2796+ do kchan=1,nchans
2797+ ans_chan(kchan)=ans(1,kchan)
2798+ ans_chan(0)=ans_chan(0)+ans(1,kchan)
2799+ enddo
2800 elseif(imode.eq.0) then
2801 c Initialize grids
2802 even=.true.
2803 min_it=min_it0
2804 do kdim=1,ndim
2805 ifold(kdim)=1
2806- do kint=0,nint_used
2807- xgrid(kint,kdim)=dble(kint)/nint_used
2808+ do kchan=1,nchans
2809+ do kint=0,nint_used
2810+ xgrid(kint,kdim,kchan)=dble(kint)/nint_used
2811+ nhits(kint,kdim,kchan)=0
2812+ enddo
2813+ regridded(kchan)=.true.
2814 enddo
2815 enddo
2816+ do kchan=1,maxchannels
2817+ nhits_in_grids(kchan)=0
2818+ enddo
2819 call init_ave_virt(nint_used_virt,ndim)
2820+ do kchan=0,nchans
2821+ ans_chan(kchan)=0d0
2822+ enddo
2823+ if (double_events) then
2824+c when double events, start with the very first channel
2825+c only. For the first iteration, we compute each channel
2826+c separately.
2827+ ans_chan(0)=1d0
2828+ ans_chan(1)=1d0
2829+ ncalls0=ncalls0/nchans
2830+ endif
2831 elseif(imode.eq.1) then
2832 c Initialize upper bounding envelope
2833- xint=ans(1)
2834- xint_virt=ans(5)
2835+ do kchan=1,nchans
2836+ xint(kchan)=ans(1,kchan)
2837+ xint_virt(kchan)=ans(5,kchan)
2838+ enddo
2839 even=.false.
2840 min_it=min_it1
2841 do kdim=1,ndim
2842@@ -166,36 +201,59 @@
2843 $ ,nint_used_virt
2844 stop
2845 endif
2846- do kint=1,nintcurr
2847- ymax(kint,kdim)=xint**(1d0/ndim)
2848+ do kchan=1,nchans
2849+ do kint=1,nintcurr
2850+ ymax(kint,kdim,kchan)=xint(kchan)**(1d0/ndim)
2851+ enddo
2852 enddo
2853 enddo
2854- ymax_virt=xint_virt
2855+ do kchan=1,nchans
2856+ ymax_virt(kchan)=xint_virt(kchan)
2857+ enddo
2858+ ans_chan(0)=0d0
2859+ do kchan=1,nchans
2860+ ans_chan(kchan)=ans(1,kchan)
2861+ ans_chan(0)=ans_chan(0)+ans(1,kchan)
2862+ enddo
2863 endif
2864+ cross_section=ans_chan(0)
2865 nit=0
2866 nit_included=0
2867 do i=1,nintegrals
2868- ans(i)=0d0
2869- unc(i)=0d0
2870+ do kchan=0,nchans
2871+ ans(i,kchan)=0d0
2872+ unc(i,kchan)=0d0
2873+ enddo
2874 do j=1,3
2875 ans3(i,j)=0d0
2876 unc3(i,j)=0d0
2877 enddo
2878 enddo
2879+ do i=1,2
2880+ HwU_values(i)=0d0
2881+ enddo
2882+cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2883 c Main loop over the iterations
2884 10 continue
2885-c This makes sure that current stdout is written to log.txt and cache is
2886-c emptied.
2887+ do kchan=1,nchans
2888+ np=0
2889+ do kint=1,nint_used
2890+ np=np+nhits(kint,1,kchan)
2891+ enddo
2892+ write (*,250) 'channel',kchan,':',iconfigs(kchan)
2893+ $ ,regridded(kchan),np,nhits_in_grids(kchan),ans_chan(kchan)
2894+ $ ,ans(2,kchan),virtual_fraction(kchan)
2895+ enddo
2896 call flush(6)
2897 if(nit.ge.nitmax) then
2898 c We did enough iterations, update arguments and return
2899- if(imode.eq.0) xint=ans(1)
2900- if(imode.eq.0) xint_virt=ans(5)
2901- if (nit_included.ge.2) then
2902- chi2(1)=chi2(1)/dble(nit_included-1)
2903- else
2904- chi2(1)=0d0
2905- endif
2906+ do kchan=0,nchans
2907+ if (nit_included.ge.2) then
2908+ chi2(1,kchan)=chi2(1,kchan)/dble(nit_included-1)
2909+ else
2910+ chi2(1,kchan)=0d0
2911+ endif
2912+ enddo
2913 write (*,*) '-------'
2914 ncalls0=ncalls*kpoint_iter ! return number of points used
2915 if (double_events) then
2916@@ -203,6 +261,17 @@
2917 else
2918 nitmax=nit_included
2919 endif
2920+ cross_section=ans(2,0)
2921+ do kchan=1,nchans
2922+ if (regridded(kchan)) then
2923+ np=0
2924+ do kint=1,nint_used
2925+ np=np+nhits(kint,1,kchan)
2926+ enddo
2927+ nhits_in_grids(kchan)=np ! set equal to number of points
2928+ ! used for last update
2929+ endif
2930+ enddo
2931 return
2932 endif
2933 nit=nit+1
2934@@ -217,29 +286,51 @@
2935 ncalls=ncalls0
2936 write (*,*) 'Update # PS points: ',ncalls0,' --> ',ncalls
2937 endif
2938+ npoints=ncalls
2939 c Reset the accumulated results for grid updating
2940 if(imode.eq.0) then
2941- do kdim=1,ndim
2942- do kint=0,nint_used
2943- xacc(kint,kdim)=0
2944- if(kint.gt.0) then
2945- nhits(kint,kdim)=0
2946+ do kchan=1,nchans
2947+ if (regridded(kchan).or.reset) then ! only reset if grids were
2948+ ! updated (or forced reset)
2949+ if (regridded(kchan) .and. .not. reset) then
2950+ np=0
2951+ do kint=1,nint_used
2952+ np=np+nhits(kint,1,kchan)
2953+ enddo
2954+ nhits_in_grids(kchan)=np ! set equal to number of
2955+ ! points used for last update
2956+ elseif (regridded(kchan) .and. reset) then
2957+ nhits_in_grids(kchan)=0
2958 endif
2959- enddo
2960+ do kdim=1,ndim
2961+ do kint=0,nint_used
2962+ xacc(kint,kdim,kchan)=0
2963+ if(kint.gt.0) then
2964+ nhits(kint,kdim,kchan)=0
2965+ endif
2966+ enddo
2967+ enddo
2968+ endif
2969 enddo
2970+ reset=.false.
2971 endif
2972- do i=1,nintegrals
2973- vtot(i)=0
2974- etot(i)=0
2975+ do kchan=0,nchans
2976+ do i=1,nintegrals
2977+ vtot(i,kchan)=0
2978+ etot(i,kchan)=0
2979+ enddo
2980 enddo
2981 kpoint_iter=0
2982 do i=1,nintegrals
2983 non_zero_point(i)=0
2984 enddo
2985+cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2986 c Loop over PS points
2987 2 kpoint_iter=kpoint_iter+1
2988 do kpoint=1,ncalls
2989 new_point=.true.
2990+c first determine which integration channel we want to pick this point from
2991+ call get_channel(ans_chan,vol_chan)
2992 c find random x, and its random cell
2993 do kdim=1,ndim
2994 kfold(kdim)=1
2995@@ -260,16 +351,17 @@
2996 enddo
2997 ifirst=0
2998 1 continue
2999- vol=1
3000+ vol=1d0/vol_chan * wgt_mult
3001 c c convert 'flat x' ('rand') to 'vegas x' ('x') and include jacobian ('vol')
3002 do kdim=1,ndim
3003 nintcurr=nint_used/ifold(kdim)
3004 icell(kdim)=ncell(kdim)+(kfold(kdim)-1)*nintcurr
3005- dx(kdim)=xgrid(icell(kdim),kdim)-xgrid(icell(kdim)-1,kdim)
3006+ dx(kdim)=xgrid(icell(kdim),kdim,ichan)-xgrid(icell(kdim)-1
3007+ $ ,kdim,ichan)
3008 vol=vol*dx(kdim)*nintcurr
3009- x(kdim)=xgrid(icell(kdim)-1,kdim)+rand(kdim)*dx(kdim)
3010- if(imode.eq.0)
3011- & nhits(icell(kdim),kdim)=nhits(icell(kdim),kdim)+1
3012+ x(kdim)=xgrid(icell(kdim)-1,kdim,ichan)+rand(kdim)*dx(kdim)
3013+ if(imode.eq.0) nhits(icell(kdim),kdim,ichan)=
3014+ $ nhits(icell(kdim),kdim,ichan)+1
3015 enddo
3016 call get_ave_virt(x,nint_used_virt,ndim,average_virtual)
3017 c contribution to integral
3018@@ -297,13 +389,14 @@
3019 if(imode.eq.0) then
3020 c accumulate the function in xacc(icell(kdim),kdim) to adjust the grid later
3021 do kdim=1,ndim
3022- xacc(icell(kdim),kdim)=xacc(icell(kdim),kdim)+f(1)
3023+ xacc(icell(kdim),kdim,ichan)=
3024+ $ xacc(icell(kdim),kdim,ichan) + f(1)
3025 enddo
3026 c Set the Born contribution (to compute the average_virtual) to zero if
3027 c the virtual was not computed for this phase-space point. Compensate by
3028 c including the virtual_fraction.
3029 if (f(3).ne.0d0) then
3030- f(6)=f(6)/virtual_fraction
3031+ f(6)=f(6)/virtual_fraction(ichan)
3032 call fill_ave_virt(x,nint_used_virt,ndim,f(3),f(6))
3033 else
3034 f(6)=0d0
3035@@ -312,7 +405,7 @@
3036 c update the upper bounding envelope total rate
3037 prod=1d0
3038 do kdim=1,ndim
3039- prod=prod*ymax(ncell(kdim),kdim)
3040+ prod=prod*ymax(ncell(kdim),kdim,ichan)
3041 enddo
3042 prod=(f(1)/prod)
3043 if (prod.gt.1d0) then
3044@@ -324,14 +417,16 @@
3045 prod=min(2d0,prod)
3046 prod=prod**(1d0/dble(ndim))
3047 do kdim=1,ndim
3048- ymax(ncell(kdim),kdim)=ymax(ncell(kdim),kdim)*prod
3049+ ymax(ncell(kdim),kdim,ichan)=
3050+ $ ymax(ncell(kdim),kdim,ichan)*prod
3051 enddo
3052 endif
3053 c Update the upper bounding envelope virtual. Do not include the
3054 c enhancement due to the virtual_fraction. (And again limit by factor 2
3055 c at most).
3056- if (f(5)*virtual_fraction.gt.ymax_virt) ymax_virt=min(f(5)
3057- $ *virtual_fraction,ymax_virt*2d0)
3058+ if (f(5)*virtual_fraction(ichan).gt.ymax_virt(ichan))
3059+ $ ymax_virt(ichan)=min(f(5)*virtual_fraction(ichan)
3060+ $ ,ymax_virt(ichan)*2d0)
3061 c for consistent printing in the log files (in particular when doing LO
3062 c runs), set also f(6) to zero when imode.eq.1 and the virtuals are not
3063 c included.
3064@@ -342,8 +437,8 @@
3065 enddo
3066 c Add the PS point to the result of this iteration
3067 do i=1,nintegrals
3068- vtot(i)=vtot(i)+f(i)
3069- etot(i)=etot(i)+f(i)**2
3070+ vtot(i,ichan)=vtot(i,ichan)+f(i)
3071+ etot(i,ichan)=etot(i,ichan)+f(i)**2
3072 enddo
3073 if (f(1).ne.0d0) call HwU_add_points
3074 enddo
3075@@ -365,32 +460,74 @@
3076 c that pass cuts.
3077 if (non_zero_point(1).lt.int(0.99*ncalls)
3078 & .and. double_events) goto 2
3079-
3080+c This is the loop over all the channels for the very first iteration.
3081+ if (imode.eq.0 .and. nit.eq.1 .and. double_events) then
3082+ do kchan=nchans,1,-1
3083+ if (ans_chan(kchan).eq.1d0) then
3084+ do i=1,nintegrals
3085+ vtot(i,kchan)=vtot(i,kchan)/dble(ntotcalls(i))
3086+ etot(i,kchan)=etot(i,kchan)/dble(ntotcalls(i))
3087+ etot(i,kchan)=sqrt(abs(etot(i,kchan)-vtot(i,kchan)**2)
3088+ $ /dble(ntotcalls(i)))
3089+ enddo
3090+ if (kchan.eq.nchans) exit
3091+ ans_chan(kchan)=0d0
3092+ ans_chan(kchan+1)=1d0
3093+ do i=1,nintegrals
3094+ ntotcalls(i)=0
3095+ non_zero_point(i)=0
3096+ enddo
3097+ kpoint_iter=0
3098+ goto 2
3099+ endif
3100+ enddo
3101+c set the total result for the first iteration as the sum over all the channels
3102+ do i=1,nintegrals
3103+ do kchan=1,nchans
3104+ vtot(i,0)=vtot(i,0)+vtot(i,kchan)
3105+ etot(i,0)=etot(i,0)+etot(i,kchan)**2
3106+ enddo
3107+ etot(i,0)=sqrt(etot(i,0))
3108+ enddo
3109+ ncalls0=ncalls0*nchans
3110+ endif
3111+cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
3112 c Iteration done. Update the accumulated results and print them to the
3113 c screen
3114 do i=1,nintegrals
3115- vtot(i)=vtot(i)/dble(ntotcalls(i))
3116- etot(i)=etot(i)/dble(ntotcalls(i))
3117+ if (imode.eq.0 .and. nit.eq.1 .and. double_events) then
3118+ continue
3119+ else
3120+ do kchan=nchans,0,-1
3121+ if (kchan.ne.0) then
3122+ vtot(i,0)=vtot(i,0)+vtot(i,kchan)
3123+ etot(i,0)=etot(i,0)+etot(i,kchan)
3124+ endif
3125+ vtot(i,kchan)=vtot(i,kchan)/dble(ntotcalls(i))
3126+ etot(i,kchan)=etot(i,kchan)/dble(ntotcalls(i))
3127 c the abs is to avoid tiny negative values
3128- etot(i)=sqrt(abs(etot(i)-vtot(i)**2)
3129- $ /dble(ntotcalls(i)))
3130- if (vtot(i).ne.0d0) then
3131- efrac(i)=abs(etot(i)/vtot(i))
3132+ etot(i,kchan)=sqrt(abs(etot(i,kchan)-vtot(i,kchan)**2)
3133+ $ /dble(ntotcalls(i)))
3134+ enddo
3135+ endif
3136+ if (vtot(i,0).ne.0d0) then
3137+ efrac(i)=abs(etot(i,0)/vtot(i,0))
3138 else
3139 efrac(i)=0d0
3140 endif
3141 enddo
3142 do i=1,nintegrals
3143 write(*,'(a,1x,e10.4,1x,a,1x,e10.4,1x,a,1x,f7.3,1x,a)')
3144- $ title(i)//' =',vtot(i),' +/- ',etot(i),' (',efrac(i)*100d0
3145- $ ,'%)'
3146+ $ title(i)//' =',vtot(i,0),' +/- ',etot(i,0),' (',efrac(i)
3147+ $ *100d0 ,'%)'
3148 enddo
3149 C If there was a large fluctation in this iteration, be careful with
3150 C including it in the accumalated results and plots.
3151- if (efrac(1).gt.0.3d0 .and. iappl.eq.0) then
3152+ if (efrac(1).gt.0.3d0 .and. iappl.eq.0 .and. nit.gt.3) then
3153 c Do not include the results in the plots
3154 if (fixed_order) call accum(.false.)
3155- if (fixed_order) call HwU_accum_iter(.false.,ntotcalls(1))
3156+ if (fixed_order) call HwU_accum_iter(.false.,ntotcalls(1)
3157+ $ ,HwU_values)
3158 endif
3159 if (efrac(1).gt.0.3d0 .and. nit.gt.3 .and. iappl.eq.0) then
3160 c Do not include the results in the updating of the grids.
3161@@ -401,7 +538,7 @@
3162 c empty the accumalated results for the MINT grids
3163 if (imode.eq.0) then
3164 c emptying accum. results is done above when the iteration starts
3165- continue
3166+ reset=.true.
3167 elseif (imode.eq.1) then
3168 c Cannot really skip the increase of the upper bounding envelope. So,
3169 c simply continue here. Note that no matter how large the integrand for
3170@@ -423,33 +560,56 @@
3171 nit_included=0
3172 c Reset the MINT grids
3173 if (imode.eq.0) then
3174- do kdim=1,ndim
3175- do kint=0,nint_used
3176- xgrid(kint,kdim)=dble(kint)/nint_used
3177+ do kchan=1,nchans
3178+ do kdim=1,ndim
3179+ do kint=0,nint_used
3180+ xgrid(kint,kdim,kchan)=dble(kint)/nint_used
3181+ enddo
3182+ regridded(kchan)=.true.
3183 enddo
3184 enddo
3185+ do kchan=1,maxchannels
3186+ nhits_in_grids(kchan)=0
3187+ enddo
3188 call init_ave_virt(nint_used_virt,ndim)
3189+ do kchan=0,nchans
3190+ ans_chan(kchan)=0d0
3191+ enddo
3192+ if (double_events) then
3193+ ans_chan(0)=1d0
3194+ ans_chan(1)=1d0
3195+ ncalls0=ncalls0/nchans
3196+ endif
3197 elseif (imode.eq.1) then
3198 do kdim=1,ndim
3199 nintcurr=nint_used/ifold(kdim)
3200- do kint=1,nintcurr
3201- ymax(kint,kdim)=xint**(1d0/ndim)
3202+ do kchan=1,nchans
3203+ do kint=1,nintcurr
3204+ ymax(kint,kdim,kchan)=xint(kchan)**(1d0/ndim)
3205+ enddo
3206 enddo
3207 nintcurr_virt=nint_used_virt/ifold(kdim)
3208 enddo
3209- ymax_virt=xint_virt
3210+ do kchan=1,nchans
3211+ ymax_virt(kchan)=xint_virt(kchan)
3212+ enddo
3213 endif
3214 call reset_MC_grid ! reset the grid for the integers
3215 if (fixed_order) call initplot ! Also reset all the plots
3216 do i=1,nintegrals
3217- ans(i)=0d0
3218- unc(i)=0d0
3219- chi2(i)=0d0
3220+ do kchan=0,nchans
3221+ ans(i,kchan)=0d0
3222+ unc(i,kchan)=0d0
3223+ chi2(i,kchan)=0d0
3224+ enddo
3225 do j=1,3
3226 ans3(i,j)=0d0
3227 unc3(i,j)=0d0
3228 enddo
3229 enddo
3230+ do i=1,2
3231+ HwU_values(i)=0d0
3232+ enddo
3233 bad_iteration=.false.
3234 else
3235 bad_iteration=.true.
3236@@ -458,81 +618,82 @@
3237 else
3238 bad_iteration=.false.
3239 endif
3240+ HwU_values(1)=etot(1,0)
3241+ HwU_values(2)=unc(1,0)
3242 if(nit.eq.1) then
3243- do i=1,nintegrals
3244- ans(i)=vtot(i)
3245- unc(i)=etot(i)
3246+ do kchan=0,nchans
3247+ do i=1,nintegrals
3248+ ans(i,kchan)=vtot(i,kchan)
3249+ unc(i,kchan)=etot(i,kchan)
3250+ enddo
3251+ ans_chan(kchan)=ans(1,kchan)
3252 enddo
3253 write (*,'(a,1x,e10.4)') 'Chi^2 per d.o.f.',0d0
3254 else
3255 c prevent annoying division by zero for nearly zero
3256 c integrands
3257+ do kchan=nchans,0,-1 ! go backwards so that kchan=0 goes last
3258+ ! (this makes sure central value is
3259+ ! correctly updated).
3260 do i=1,nintegrals
3261- if(etot(i).eq.0.and.unc(i).eq.0) then
3262- if(ans(i).eq.vtot(i) .and. i.eq.1) then
3263+ if(etot(i,0).eq.0.and.unc(i,0).eq.0) then
3264+ if(ans(i,0).eq.vtot(i,0) .and. i.eq.1) then
3265 c double the number of points for the next iteration
3266 if (double_events) ncalls0=ncalls0*2
3267 goto 10
3268 else
3269- unc(i)=abs(vtot(i)-ans(i))
3270- etot(i)=abs(vtot(i)-ans(i))
3271+ unc(i,kchan)=abs(vtot(i,kchan)-ans(i,kchan))
3272+ etot(i,kchan)=abs(vtot(i,kchan)-ans(i,kchan))
3273 endif
3274- elseif(etot(i).eq.0) then
3275- etot(i)=unc(i)
3276- elseif(unc(i).eq.0) then ! 1st iteration; set to a large value
3277- unc(i)=etot(i)*1d99
3278+ elseif(etot(i,0).eq.0) then
3279+ etot(i,kchan)=unc(i,kchan)
3280+ elseif(unc(i,0).eq.0) then ! 1st iteration; set to a large value
3281+ unc(i,kchan)=etot(i,kchan)*1d99
3282 endif
3283- if (i.ne.1 .and. (etot(i).eq.0 .or. unc(i).eq.0)) then
3284- ans(i)=0d0
3285- unc(i)=0d0
3286- chi2(i)=0d0
3287+ if (i.ne.1 .and. (etot(i,0).eq.0 .or. unc(i,0).eq.0)) then
3288+ ans(i,kchan)=0d0
3289+ unc(i,kchan)=0d0
3290+ chi2(i,kchan)=0d0
3291 else
3292- ans(i)=(ans(i)/unc(i)+vtot(i)/etot(i))/
3293- & (1/unc(i)+1/etot(i))
3294- unc(i)=1/sqrt(1/unc(i)**2+1/etot(i)**2)
3295- chi2(i)=chi2(i)+(vtot(i)-ans(i))**2/etot(i)**2
3296+ ans(i,kchan)=(ans(i,kchan)/unc(i,0)+vtot(i,kchan)/etot(i
3297+ $ ,0))/(1/unc(i,0)+1/etot(i,0))
3298+ unc(i,kchan)=1/sqrt(1/unc(i,kchan)**2+1/etot(i,kchan)**2)
3299+ chi2(i,kchan)=chi2(i,kchan)+(vtot(i,kchan)-ans(i,kchan))
3300+ $ **2/etot(i,kchan)**2
3301 endif
3302 enddo
3303- write (*,'(a,1x,e10.4)') 'Chi^2=',(vtot(1)-ans(1))**2
3304- $ /etot(1)**2
3305+ ans_chan(kchan)=ans(1,kchan)
3306+ enddo
3307+ write (*,'(a,1x,e10.4)') 'Chi^2=',(vtot(1,0)-ans(1,0))**2
3308+ $ /etot(1,0)**2
3309 endif
3310-
3311 nit_included=nit_included+1
3312 do i=1,nintegrals
3313- if (ans(i).ne.0d0) then
3314- efrac(i)=abs(unc(i)/ans(i))
3315+ if (ans(i,0).ne.0d0) then
3316+ efrac(i)=abs(unc(i,0)/ans(i,0))
3317 else
3318 efrac(i)=0d0
3319 endif
3320 write(*,'(a,1x,e10.4,1x,a,1x,e10.4,1x,a,1x,f7.3,1x,a)')
3321- $ 'accumulated results '//title(i)//' =',ans(i),' +/- '
3322- $ ,unc(i) ,' (',efrac(i)*100d0,'%)'
3323+ $ 'accumulated results '//title(i)//' =',ans(i,0),' +/- '
3324+ $ ,unc(i,0) ,' (',efrac(i)*100d0,'%)'
3325 enddo
3326+ cross_section=ans(1,0)
3327 if (nit_included.le.1) then
3328 write (*,'(a,1x,e10.4)') 'accumulated result Chi^2 per DoF ='
3329 $ ,0d0
3330 else
3331 write (*,'(a,1x,e10.4)') 'accumulated result Chi^2 per DoF =',
3332- & chi2(1)/dble(nit_included-1)
3333+ & chi2(1,0)/dble(nit_included-1)
3334 endif
3335 if (imode.eq.0) then
3336-c Update the average_virtual: a_new=(virt+a_old*born)/born
3337- if (vtot(6).ne.0d0) then
3338- if (average_virtual.eq.0d0) then ! i.e. first iteration
3339- average_virtual=vtot(3)/vtot(6)+average_virtual
3340- else ! give some importance to the iterations already done
3341- average_virtual=(vtot(3)/vtot(6)+average_virtual*2d0)/2d0
3342- endif
3343- endif
3344 c Update the fraction of the events for which we include the virtual corrections
3345 c in the calculation
3346- virtual_fraction=max(min(virtual_fraction*max(min(2d0*etot(3)
3347- $ /etot(1),2d0),0.25d0),1d0),Min_virt_fraction)
3348- write (*,'(a,1x,f7.3,1x,f7.3)') 'update virtual fraction to:'
3349- $ ,virtual_fraction,average_virtual
3350- elseif (imode.eq.1) then
3351- write (*,'(a,1x,f7.3,1x,f7.3)') 'virtual fraction is:'
3352- $ ,virtual_fraction,average_virtual
3353+ do kchan=1,nchans
3354+ virtual_fraction(kchan)=max(min(virtual_fraction(kchan)
3355+ $ *max(min(2d0*etot(3,kchan)/etot(1,kchan),2d0),0.25d0)
3356+ $ ,1d0),Min_virt_fraction)
3357+ enddo
3358 endif
3359 c Update the results of the last tree iterations
3360 do i=1,nintegrals
3361@@ -540,8 +701,8 @@
3362 ans3(i,j)=ans3(i,j+1)
3363 unc3(i,j)=unc3(i,j+1)
3364 enddo
3365- ans3(i,3)=vtot(i)
3366- unc3(i,3)=etot(i)
3367+ ans3(i,3)=vtot(i,0)
3368+ unc3(i,3)=etot(i,0)
3369 enddo
3370 c Compute the results of the last three iterations
3371 if (nit_included.ge.4) then
3372@@ -582,9 +743,12 @@
3373 endif
3374 if(imode.eq.0) then
3375 c Iteration is finished; now rearrange the grid
3376- do kdim=1,ndim
3377- call regrid(xacc(0,kdim),xgrid(0,kdim),nhits(1,kdim)
3378- $ ,nint_used)
3379+ do kchan=1,nchans
3380+ do kdim=1,ndim
3381+ call regrid(xacc(0,kdim,kchan),xgrid(0,kdim,kchan)
3382+ $ ,nhits(1,kdim,kchan),nint_used,nhits_in_grids(kchan)
3383+ $ ,regridded(kchan))
3384+ enddo
3385 enddo
3386 call regrid_ave_virt(nint_used_virt,ndim)
3387 c Regrid the MC over integers (used for the MC over FKS dirs)
3388@@ -592,13 +756,14 @@
3389 endif
3390 c Quit if the desired accuracy has been reached
3391 if (nit_included.ge.min_it .and. accuracy.gt.0d0) then
3392- if (unc(1)/ans(1)*max(1d0,chi2(1)/dble(nit_included-1))
3393+ if (unc(1,0)/ans(1,0)*max(1d0,chi2(1,0)/dble(nit_included-1))
3394 $ .lt.accuracy) then
3395 write (*,*) 'Found desired accuracy'
3396 nit=nitmax
3397 c Improve the stats in the plots
3398 if (fixed_order) call accum(.true.)
3399- if (fixed_order) call HwU_accum_iter(.true.,ntotcalls(1))
3400+ if (fixed_order) call HwU_accum_iter(.true.,ntotcalls(1)
3401+ $ ,HwU_values)
3402 goto 10
3403 elseif(unc_l3(1)/ans_l3(1)*max(1d0,chi2_l3(1)).lt.accuracy)
3404 $ then
3405@@ -606,20 +771,24 @@
3406 & 'Found desired accuracy in last 3 iterations'
3407 nit=nitmax
3408 do i=1,nintegrals
3409- ans(i)=ans_l3(i)
3410- unc(i)=unc_l3(i)
3411- chi2(i)=chi2_l3(i)*dble(nit_included-1)
3412+ ans(i,0)=ans_l3(i)
3413+ unc(i,0)=unc_l3(i)
3414+ chi2(i,0)=chi2_l3(i)*dble(nit_included-1)
3415 enddo
3416 c Improve the stats in the plots
3417 if (fixed_order) call accum(.true.)
3418- if (fixed_order) call HwU_accum_iter(.true.,ntotcalls(1))
3419+ if (fixed_order) call HwU_accum_iter(.true.,ntotcalls(1)
3420+ $ ,HwU_values)
3421 goto 10
3422 endif
3423 endif
3424 c Double the number of intervals in the grids if not yet reach the maximum
3425 if (2*nint_used.le.nintervals .and. double_events) then
3426- do kdim=1,ndim
3427- call double_grid(xgrid(0,kdim),nint_used)
3428+ do kchan=1,nchans
3429+ do kdim=1,ndim
3430+ call double_grid(xgrid(0,kdim,kchan),nhits(1,kdim,kchan)
3431+ $ ,nint_used)
3432+ enddo
3433 enddo
3434 nint_used=2*nint_used
3435 endif
3436@@ -632,33 +801,49 @@
3437 if (double_events) ncalls0=ncalls0*2
3438 c Also improve stats in plots
3439 if (fixed_order) call accum(.true.)
3440- if (fixed_order) call HwU_accum_iter(.true.,ntotcalls(1))
3441+ if (fixed_order) call HwU_accum_iter(.true.,ntotcalls(1)
3442+ $ ,HwU_values)
3443 c Do next iteration
3444 goto 10
3445+ return
3446+ 250 format(a7,i5,1x,a1,1x,i5,1x,l,1x,i8,1x,i8,2x,e10.4,2x,e10.4,2x
3447+ $ ,e10.4)
3448 end
3449
3450- subroutine double_grid(xgrid,ninter)
3451+ subroutine double_grid(xgrid,nhits,ninter)
3452 implicit none
3453 include "mint.inc"
3454- integer ninter
3455+ integer ninter,nhits(nintervals)
3456 real * 8 xgrid(0:nintervals)
3457 integer i
3458 do i=ninter,1,-1
3459 xgrid(i*2)=xgrid(i)
3460 xgrid(i*2-1)=(xgrid(i)+xgrid(i-1))/2d0
3461+ nhits(i*2)=nhits(i)/2
3462+ nhits(i*2-1)=nhits(i)-nhits(i*2)
3463 enddo
3464 return
3465 end
3466
3467
3468- subroutine regrid(xacc,xgrid,nhits,ninter)
3469+ subroutine regrid(xacc,xgrid,nhits,ninter,nhits_in_grid,regridded)
3470 implicit none
3471 include "mint.inc"
3472- integer ninter,nhits(nintervals)
3473+ logical regridded
3474+ integer ninter,nhits(nintervals),np,nhits_in_grid
3475 real * 8 xacc(0:nintervals),xgrid(0:nintervals)
3476 real * 8 xn(nintervals),r,tiny,xl,xu,nl,nu,sum
3477 parameter ( tiny=1d-8 )
3478 integer kint,jint
3479+c compute total number of points and update grids if large
3480+ np=0
3481+ do kint=1,ninter
3482+ np=np+nhits(kint)
3483+ enddo
3484+ regridded=.false.
3485+ if (np.lt.nhits_in_grid) return
3486+ regridded=.true.
3487+
3488 c Use the same smoothing as in VEGAS uses for the grids, i.e. use the
3489 c average of the central and the two neighbouring grid points: (Only do
3490 c this if we are already at the maximum intervals, because the doubling
3491@@ -797,33 +982,39 @@
3492 implicit none
3493 integer ndim,imode
3494 include "mint.inc"
3495- real * 8 fun,xgrid(0:nintervals,ndimmax),ymax(nintervals,ndimmax)
3496- $ ,ymax_virt,x(ndimmax)
3497- real * 8 dx(ndimmax),xx(ndimmax)
3498+ real * 8 fun,xgrid(0:nintervals,ndimmax,maxchannels)
3499+ $ ,ymax(nintervals,ndimmax,maxchannels),ymax_virt(maxchannels)
3500+ $ ,x(ndimmax)
3501+ real * 8 dx(ndimmax),xx(ndimmax),vol_chan,dummy
3502 integer icell(ndimmax),ncell(ndimmax),ncell_virt
3503 integer ifold(ndimmax),kfold(ndimmax)
3504 common/cifold/ifold
3505 real * 8 r,f(nintegrals),f1(nintegrals),ubound,vol,ran3
3506- $ ,xmmm(nintervals,ndimmax),dummy
3507+ $ ,xmmm(nintervals,ndimmax,maxchannels)
3508 real * 8 rand(ndimmax)
3509 external fun,ran3
3510 integer icalls,mcalls,kdim,kint,nintcurr,nintcurr_virt,iret,ifirst
3511 $ ,i,vn,icalls_virt,mcalls_virt,icalls_nz,icalls_virt_nz
3512- double precision average_virtual,virtual_fraction
3513+ double precision average_virtual(maxchannels)
3514+ $ ,virtual_fraction(maxchannels)
3515 common/c_avg_virt/average_virtual,virtual_fraction
3516 save icalls,mcalls,icalls_virt,mcalls_virt,xmmm,icalls_nz
3517 $ ,icalls_virt_nz
3518 logical new_point
3519 common /c_new_point/ new_point
3520 if(imode.eq.0) then
3521- do kdim=1,ndim
3522- nintcurr=nintervals/ifold(kdim)
3523- xmmm(1,kdim)=ymax(1,kdim)
3524- do kint=2,nintcurr
3525- xmmm(kint,kdim)=xmmm(kint-1,kdim)+ymax(kint,kdim)
3526- enddo
3527- do kint=1,nintcurr
3528- xmmm(kint,kdim)=xmmm(kint,kdim)/xmmm(nintcurr,kdim)
3529+ do kchan=1,nchans
3530+ do kdim=1,ndim
3531+ nintcurr=nintervals/ifold(kdim)
3532+ xmmm(1,kdim,kchan)=ymax(1,kdim,kchan)
3533+ do kint=2,nintcurr
3534+ xmmm(kint,kdim,kchan)=xmmm(kint-1,kdim,kchan)
3535+ $ +ymax(kint,kdim,kchan)
3536+ enddo
3537+ do kint=1,nintcurr
3538+ xmmm(kint,kdim,kchan)=xmmm(kint,kdim,kchan)
3539+ $ /xmmm(nintcurr,kdim,kchan)
3540+ enddo
3541 enddo
3542 enddo
3543 icalls=0
3544@@ -868,6 +1059,7 @@
3545 stop
3546 endif
3547 10 continue
3548+ call get_channel(ymax_virt,vol_chan)
3549 new_point=.true.
3550 if (vn.eq.1) then
3551 icalls_virt=icalls_virt+1
3552@@ -885,7 +1077,7 @@
3553 nintcurr=nintervals/ifold(kdim)
3554 r=ran3(.false.)
3555 do kint=1,nintcurr
3556- if(r.lt.xmmm(kint,kdim)) then
3557+ if(r.lt.xmmm(kint,kdim,ichan)) then
3558 ncell(kdim)=kint
3559 exit
3560 endif
3561@@ -896,7 +1088,7 @@
3562 if (vn.eq.2 .or. vn.eq.3) then
3563 ubound=1
3564 do kdim=1,ndim
3565- ubound=ubound*ymax(ncell(kdim),kdim)
3566+ ubound=ubound*ymax(ncell(kdim),kdim,ichan)
3567 enddo
3568 endif
3569 do kdim=1,ndim
3570@@ -907,18 +1099,19 @@
3571 enddo
3572 ifirst=0
3573 5 continue
3574- vol=1
3575+ vol=1d0/vol_chan
3576 do kdim=1,ndim
3577 nintcurr=nintervals/ifold(kdim)
3578 nintcurr_virt=nintervals_virt/ifold(kdim)
3579 icell(kdim)=ncell(kdim)+(kfold(kdim)-1)*nintcurr
3580- dx(kdim)=xgrid(icell(kdim),kdim)-xgrid(icell(kdim)-1,kdim)
3581+ dx(kdim)=xgrid(icell(kdim),kdim,ichan)-xgrid(icell(kdim)-1,kdim
3582+ $ ,ichan)
3583 vol=vol*dx(kdim)*nintervals/ifold(kdim)
3584- x(kdim)=xgrid(icell(kdim)-1,kdim)+rand(kdim)*dx(kdim)
3585+ x(kdim)=xgrid(icell(kdim)-1,kdim,ichan)+rand(kdim)*dx(kdim)
3586 enddo
3587 call get_ave_virt(x,nintcurr_virt,ndim,average_virtual)
3588 if (vn.eq.1) then
3589- ubound=ymax_virt
3590+ ubound=ymax_virt(ichan)
3591 endif
3592 dummy=fun(x,vol,ifirst,f1)
3593 do i=1,nintegrals
3594@@ -1108,20 +1301,15 @@
3595 implicit none
3596 include "mint.inc"
3597 integer kdim,ndim,ninter,i
3598- integer nvirt(nintervals_virt,ndimmax),nvirt_acc(nintervals_virt
3599- $ ,ndimmax)
3600- double precision ave_virt(nintervals_virt,ndimmax)
3601- $ ,ave_virt_acc(nintervals_virt,ndimmax)
3602- $ ,ave_born_acc(nintervals_virt ,ndimmax)
3603- common/c_ave_virt/ave_virt,ave_virt_acc,ave_born_acc,nvirt
3604- $ ,nvirt_acc
3605- do kdim=1,ndim
3606- do i=1,ninter
3607- nvirt(i,kdim)=0
3608- ave_virt(i,kdim)=0d0
3609- nvirt_acc(i,kdim)=0
3610- ave_virt_acc(i,kdim)=0d0
3611- ave_born_acc(i,kdim)=0d0
3612+ do kchan=1,nchans
3613+ do kdim=1,ndim
3614+ do i=1,ninter
3615+ nvirt(i,kdim,kchan)=0
3616+ ave_virt(i,kdim,kchan)=0d0
3617+ nvirt_acc(i,kdim,kchan)=0
3618+ ave_virt_acc(i,kdim,kchan)=0d0
3619+ ave_born_acc(i,kdim,kchan)=0d0
3620+ enddo
3621 enddo
3622 enddo
3623 return
3624@@ -1131,20 +1319,14 @@
3625 implicit none
3626 include "mint.inc"
3627 integer kdim,ndim,ninter,ncell
3628- double precision x(ndimmax),average_virtual
3629- integer nvirt(nintervals_virt,ndimmax),nvirt_acc(nintervals_virt
3630- $ ,ndimmax)
3631- double precision ave_virt(nintervals_virt,ndimmax)
3632- $ ,ave_virt_acc(nintervals_virt,ndimmax)
3633- $ ,ave_born_acc(nintervals_virt ,ndimmax)
3634- common/c_ave_virt/ave_virt,ave_virt_acc,ave_born_acc,nvirt
3635- $ ,nvirt_acc
3636- average_virtual=0d0
3637+ double precision x(ndimmax),average_virtual(maxchannels)
3638+ average_virtual(ichan)=0d0
3639 do kdim=1,ndim
3640 ncell=min(int(x(kdim)*ninter)+1,ninter)
3641- average_virtual=average_virtual+ave_virt(ncell,kdim)
3642+ average_virtual(ichan)=average_virtual(ichan)+
3643+ & ave_virt(ncell,kdim,ichan)
3644 enddo
3645- average_virtual=average_virtual/ndim
3646+ average_virtual(ichan)=average_virtual(ichan)/ndim
3647 return
3648 end
3649
3650@@ -1153,18 +1335,13 @@
3651 include "mint.inc"
3652 integer kdim,ndim,ninter,ncell
3653 double precision x(ndimmax),virtual,born
3654- integer nvirt(nintervals_virt,ndimmax),nvirt_acc(nintervals_virt
3655- $ ,ndimmax)
3656- double precision ave_virt(nintervals_virt,ndimmax)
3657- $ ,ave_virt_acc(nintervals_virt,ndimmax)
3658- $ ,ave_born_acc(nintervals_virt ,ndimmax)
3659- common/c_ave_virt/ave_virt,ave_virt_acc,ave_born_acc,nvirt
3660- $ ,nvirt_acc
3661 do kdim=1,ndim
3662 ncell=min(int(x(kdim)*ninter)+1,ninter)
3663- nvirt_acc(ncell,kdim)=nvirt_acc(ncell,kdim)+1
3664- ave_virt_acc(ncell,kdim)=ave_virt_acc(ncell,kdim)+virtual
3665- ave_born_acc(ncell,kdim)=ave_born_acc(ncell,kdim)+born
3666+ nvirt_acc(ncell,kdim,ichan)=nvirt_acc(ncell,kdim,ichan)+1
3667+ ave_virt_acc(ncell,kdim,ichan)=ave_virt_acc(ncell,kdim,ichan)
3668+ $ +virtual
3669+ ave_born_acc(ncell,kdim,ichan)=ave_born_acc(ncell,kdim,ichan)
3670+ $ +born
3671 enddo
3672 return
3673 end
3674@@ -1173,35 +1350,38 @@
3675 implicit none
3676 include "mint.inc"
3677 integer ninter,ndim,kdim,i
3678- integer nvirt(nintervals_virt,ndimmax),nvirt_acc(nintervals_virt
3679- $ ,ndimmax)
3680- double precision ave_virt(nintervals_virt,ndimmax)
3681- $ ,ave_virt_acc(nintervals_virt,ndimmax)
3682- $ ,ave_born_acc(nintervals_virt,ndimmax)
3683- common/c_ave_virt/ave_virt,ave_virt_acc,ave_born_acc,nvirt
3684- $ ,nvirt_acc
3685-c need to solve for k_new = (virt+k_old*born)/born
3686+c need to solve for k_new = (virt+k_old*born)/born = virt/born + k_old
3687+ do kchan=1,nchans
3688 do kdim=1,ndim
3689 do i=1,ninter
3690- if (ave_born_acc(i,kdim).eq.0d0) cycle
3691- if (ave_virt(i,kdim).eq.0d0) then ! i.e. first iteration
3692- ave_virt(i,kdim)= ave_virt_acc(i,kdim)/ave_born_acc(i
3693- $ ,kdim)+ave_virt(i,kdim)
3694- else ! give some importance to the iterations already done
3695- ave_virt(i,kdim)=(ave_virt_acc(i,kdim)/ave_born_acc(i
3696- $ ,kdim)+ave_virt(i,kdim)*2d0)/2d0
3697+ if (ave_born_acc(i,kdim,kchan).eq.0d0) cycle
3698+ if (ave_virt(i,kdim,kchan).eq.0d0) then ! i.e. first iteration
3699+ ave_virt(i,kdim,kchan)= ave_virt_acc(i,kdim,kchan)
3700+ $ /ave_born_acc(i,kdim,kchan)+ave_virt(i,kdim,kchan)
3701+ else ! give some importance to the iterations already
3702+ ! done: simply base it on the number of points already
3703+ ! computed in that bin. Give half the weight to old iterations
3704+ ! k_new = [N_new*(V/B+k_old) + (N_old/2)*k_old] / [N_new+(N_old/2)]
3705+ ave_virt(i,kdim,kchan)=(nvirt_acc(i,kdim,kchan)
3706+ $ *ave_virt_acc(i,kdim,kchan)/ave_born_acc(i,kdim
3707+ $ ,kchan)+(nvirt_acc(i,kdim,kchan)+nint(nvirt(i,kdim
3708+ $ ,kchan)/2d0))*ave_virt(i,kdim,kchan))
3709+ $ /dble(nvirt_acc(i,kdim,kchan)+nint(nvirt(i,kdim
3710+ $ ,kchan)/2d0))
3711 endif
3712 enddo
3713 enddo
3714 c reset the acc values
3715 do kdim=1,ndim
3716 do i=1,ninter
3717- nvirt(i,kdim)=nvirt(i,kdim)+nvirt_acc(i,kdim)
3718- nvirt_acc(i,kdim)=0
3719- ave_born_acc(i,kdim)=0d0
3720- ave_virt_acc(i,kdim)=0d0
3721+ nvirt(i,kdim,kchan)=nvirt(i,kdim,kchan)+nvirt_acc(i,kdim
3722+ $ ,kchan)
3723+ nvirt_acc(i,kdim,kchan)=0
3724+ ave_born_acc(i,kdim,kchan)=0d0
3725+ ave_virt_acc(i,kdim,kchan)=0d0
3726 enddo
3727 enddo
3728+ enddo
3729 return
3730 end
3731
3732@@ -1210,33 +1390,83 @@
3733 implicit none
3734 include "mint.inc"
3735 integer kdim,ndim,i,ninter
3736- integer nvirt(nintervals_virt,ndimmax),nvirt_acc(nintervals_virt
3737- $ ,ndimmax)
3738- double precision ave_virt(nintervals_virt,ndimmax)
3739- $ ,ave_virt_acc(nintervals_virt,ndimmax)
3740- $ ,ave_born_acc(nintervals_virt ,ndimmax)
3741- common/c_ave_virt/ave_virt,ave_virt_acc,ave_born_acc,nvirt
3742- $ ,nvirt_acc
3743+ do kchan=1,nchans
3744 do kdim=1,ndim
3745 do i=ninter,1,-1
3746- ave_virt(i*2,kdim)=ave_virt(i,kdim)
3747- if (nvirt(i,kdim).ne.0) then
3748- nvirt(i*2,kdim)=max(nvirt(i,kdim)/2,1)
3749+ ave_virt(i*2,kdim,kchan)=ave_virt(i,kdim,kchan)
3750+ if (nvirt(i,kdim,kchan).ne.0) then
3751+ nvirt(i*2,kdim,kchan)=max(nvirt(i,kdim,kchan)/2,1)
3752 else
3753- nvirt(i*2,kdim)=0
3754+ nvirt(i*2,kdim,kchan)=0
3755 endif
3756 if (i.ne.1) then
3757- ave_virt(i*2-1,kdim)=(ave_virt(i,kdim)
3758- $ +ave_virt(i-1,kdim))/2d0
3759- if (nvirt(i,kdim)+nvirt(i-1,kdim).ne.0) then
3760- nvirt(i*2-1,kdim)=
3761- & max((nvirt(i,kdim)+nvirt(i-1,kdim))/4,1)
3762- else
3763- nvirt(i*2-1,kdim)=0
3764+ ave_virt(i*2-1,kdim,kchan)=(ave_virt(i,kdim,kchan)
3765+ $ +ave_virt(i-1,kdim,kchan))/2d0
3766+ if (nvirt(i,kdim,kchan)+nvirt(i-1,kdim,kchan).ne.0) then
3767+ nvirt(i*2-1,kdim,kchan)=
3768+ & max((nvirt(i,kdim,kchan)+nvirt(i-1,kdim,kchan))/4,1)
3769+ else
3770+ nvirt(i*2-1,kdim,kchan)=0
3771+ endif
3772+ else
3773+ if (nvirt(1,kdim,kchan).ne.0) then
3774+ nvirt(1,kdim,kchan)=max(nvirt(1,kdim,kchan)/2,1)
3775+ else
3776+ nvirt(1,kdim,kchan)=0
3777 endif
3778 endif
3779 enddo
3780 enddo
3781- return
3782- end
3783-
3784+ enddo
3785+ return
3786+ end
3787+
3788+
3789+
3790+ subroutine get_channel(ans,vol_chan)
3791+c Picks one random 'ichan' among the 'nchans' integration channels and
3792+c fills the channels common block in mint.inc.
3793+ implicit none
3794+ include 'mint.inc'
3795+ double precision ans(0:maxchannels),vol_chan,ran3,target,sum
3796+ external ran3
3797+ if (nchans.eq.1) then
3798+ ichan=1
3799+ iconfig=iconfigs(ichan)
3800+ vol_chan=1d0
3801+ elseif (nchans.gt.1) then
3802+ if (ans(0).le.0d0) then
3803+c pick one at random (flat)
3804+ ichan=int(ran3(.false.)*nchans)+1
3805+ iconfig=iconfigs(ichan)
3806+ vol_chan=1d0/dble(nchans)
3807+ else
3808+c pick one at random (weighted by cross section)
3809+ sum=0d0
3810+ do kchan=1,nchans
3811+ sum=sum+ans(kchan)
3812+ enddo
3813+ if (abs(sum-ans(0))/(sum+ans(0)).gt.1d-8) then
3814+ write (*,*) 'ERROR: sum should be equal to ans',
3815+ & sum,ans(0)
3816+ stop 1
3817+ endif
3818+ target=ans(0)*ran3(.false.)
3819+ sum=0d0
3820+ ichan=0
3821+ do while (sum.lt.target)
3822+ ichan=ichan+1
3823+ sum=sum+ans(ichan)
3824+ enddo
3825+ if (ichan.eq.0 .or. ichan.gt.nchans) then
3826+ write (*,*) 'ERROR: ichan cannot be zero or'/
3827+ $ /' larger than nchans',ichan,nchans
3828+ stop
3829+ endif
3830+ iconfig=iconfigs(ichan)
3831+ vol_chan=ans(ichan)/ans(0)
3832+ endif
3833+ endif
3834+ return
3835+ end
3836+
3837
3838=== modified file 'Template/NLO/SubProcesses/mint.inc'
3839--- Template/NLO/SubProcesses/mint.inc 2016-09-28 15:25:10 +0000
3840+++ Template/NLO/SubProcesses/mint.inc 2017-03-08 10:27:27 +0000
3841@@ -1,3 +1,11 @@
3842+* -*-fortran-*-
3843+
3844+ integer maxchannels
3845+ parameter (maxchannels=20) ! same as in amcatnlo_run_interface
3846+ integer nchans,iconfigs(maxchannels),kchan,iconfig,ichan
3847+ double precision wgt_mult
3848+ common /channels/ wgt_mult,nchans,iconfigs,iconfig,ichan
3849+
3850 c Note that the number of intervals in the integration
3851 c grids, 'nintervals', should be equal to
3852 c "nintervals = min_inter * 2^n",
3853@@ -16,3 +24,11 @@
3854
3855 double precision accuracy
3856 common /to_accuracy/ accuracy
3857+
3858+ integer nvirt(nintervals_virt,ndimmax,maxchannels)
3859+ $ ,nvirt_acc(nintervals_virt,ndimmax,maxchannels)
3860+ double precision ave_virt(nintervals_virt,ndimmax,maxchannels)
3861+ $ ,ave_virt_acc(nintervals_virt,ndimmax,maxchannels)
3862+ $ ,ave_born_acc(nintervals_virt ,ndimmax,maxchannels)
3863+ common/c_ave_virt/ave_virt,ave_virt_acc,ave_born_acc,nvirt
3864+ $ ,nvirt_acc
3865
3866=== modified file 'Template/NLO/SubProcesses/montecarlocounter.f'
3867--- Template/NLO/SubProcesses/montecarlocounter.f 2016-10-25 07:08:18 +0000
3868+++ Template/NLO/SubProcesses/montecarlocounter.f 2017-03-08 10:27:27 +0000
3869@@ -203,7 +203,7 @@
3870 # ( abs(particle_type(ipart)).ne.3 .and.
3871 # particle_type(ipart).ne.8 ) )then
3872 write(*,*)'Error #2 in check_mc_matrices',i,ipart,
3873- # particle_type(ipart)
3874+ #particle_type(ipart)
3875 stop
3876 endif
3877 enddo
3878@@ -2501,6 +2501,8 @@
3879 double precision shattmp,dot,emsca_bare,ref_scale,scalemin,
3880 &scalemax,rrnd,ran2,emscainv,dum(5),xm12,qMC,ptresc
3881 integer ileg
3882+ double precision p_born(0:3,nexternal-1)
3883+ common/pborn/p_born
3884
3885 logical emscasharp
3886 double precision emsca
3887@@ -2521,7 +2523,7 @@
3888 & xm12,dum(1),dum(2),dum(3),dum(4),dum(5),qMC,.true.)
3889
3890 emsca=2d0*sqrt(ebeam(1)*ebeam(2))
3891- scalemax=sqrt((1-xi_i_fks)*shat)
3892+ call assign_ref_scale(p_born,xi_i_fks,shat,scalemax)
3893 if(dampMCsubt)then
3894 call assign_scaleminmax(shat,xi_i_fks,scalemin,scalemax,ileg,xm12)
3895 emscasharp=(scalemax-scalemin).lt.(1d-3*scalemax)
3896@@ -2545,14 +2547,17 @@
3897
3898 subroutine assign_scaleminmax(shat,xi,xscalemin,xscalemax,ileg,xm12)
3899 implicit none
3900+ include "nexternal.inc"
3901 include "run.inc"
3902 include "madfks_mcatnlo.inc"
3903 integer i,ileg
3904 double precision shat,xi,ref_scale,xscalemax,xscalemin,xm12
3905 character*4 abrv
3906 common/to_abrv/abrv
3907+ double precision p_born(0:3,nexternal-1)
3908+ common/pborn/p_born
3909
3910- ref_scale=sqrt((1-xi)*shat)
3911+ call assign_ref_scale(p_born,xi,shat,ref_scale)
3912 xscalemin=max(shower_scale_factor*frac_low*ref_scale,scaleMClow)
3913 xscalemax=max(shower_scale_factor*frac_upp*ref_scale,
3914 & xscalemin+scaleMCdelta)
3915@@ -2568,6 +2573,33 @@
3916 end
3917
3918
3919+ subroutine assign_ref_scale(p,xii,sh,ref_sc)
3920+ implicit none
3921+ include "nexternal.inc"
3922+ double precision p(0:3,nexternal-1),xii,sh,ref_sc
3923+ integer i_scale,i
3924+ parameter(i_scale=1)
3925+
3926+ ref_sc=0d0
3927+ if(i_scale.eq.0)then
3928+c Born-level CM energy squared
3929+ ref_sc=dsqrt(max(0d0,(1-xii)*sh))
3930+ elseif(i_scale.eq.1)then
3931+c Sum of final-state transverse masses
3932+ do i=3,nexternal-1
3933+ ref_sc=ref_sc+dsqrt(max(0d0,(p(0,i)+p(3,i))*(p(0,i)-p(3,i))))
3934+ enddo
3935+ ref_sc=ref_sc/2d0
3936+ else
3937+ write(*,*)'Wrong i_scale in assign_ref_scale',i_scale
3938+ stop
3939+ endif
3940+c Safety threshold for the reference scale
3941+ ref_sc=max(ref_sc,30d0)
3942+
3943+ return
3944+ end
3945+
3946
3947 subroutine dinvariants_dFKS(ileg,s,x,yi,yj,xm12,xm22,dw1dx,dw1dy,dw2dx,dw2dy)
3948 c Returns derivatives of Mandelstam invariants with respect to FKS variables
3949
3950=== modified file 'Template/NLO/SubProcesses/setcuts.f'
3951--- Template/NLO/SubProcesses/setcuts.f 2016-11-14 10:30:46 +0000
3952+++ Template/NLO/SubProcesses/setcuts.f 2017-03-08 10:27:27 +0000
3953@@ -144,6 +144,7 @@
3954 include 'coupl.inc'
3955 include 'nFKSconfigs.inc'
3956 include "fks_info.inc"
3957+ include "mint.inc"
3958 LOGICAL IS_A_J(NEXTERNAL),IS_A_LP(NEXTERNAL),IS_A_LM(NEXTERNAL)
3959 LOGICAL IS_A_PH(NEXTERNAL)
3960 COMMON /TO_SPECISA/IS_A_J,IS_A_LP,IS_A_LM,IS_A_PH
3961@@ -151,13 +152,14 @@
3962 double precision pmass(-nexternal:0,lmaxconfigs)
3963 double precision pwidth(-nexternal:0,lmaxconfigs)
3964 integer pow(-nexternal:0,lmaxconfigs)
3965- integer itree(2,-max_branch:-1),iconfig
3966- common /to_itree/itree,iconfig
3967+ integer itree(2,-max_branch:-1),iconf
3968+ common /to_itree/itree,iconf
3969 INTEGER NFKSPROCESS
3970 COMMON/C_NFKSPROCESS/NFKSPROCESS
3971- double precision taumin(fks_configs),taumin_s(fks_configs)
3972- & ,taumin_j(fks_configs),stot,xk(nexternal)
3973- save taumin,taumin_s,taumin_j,stot
3974+ double precision taumin(fks_configs,maxchannels)
3975+ $ ,taumin_s(fks_configs,maxchannels),taumin_j(fks_configs
3976+ $ ,maxchannels),stot,xk(nexternal)
3977+ save taumin,taumin_s,taumin_j
3978 integer i,j,k,d1,d2,iFKS,nt
3979 double precision xm(-nexternal:nexternal),xm1,xm2,xmi
3980 double precision xw(-nexternal:nexternal),xw1,xw2,xwi
3981@@ -170,11 +172,12 @@
3982 double precision mass_min(-nexternal:nexternal),masslow(
3983 $ -nexternal:-1),widthlow(-nexternal:-1),sum_all_s
3984 integer t_channel
3985- integer cBW_FKS_level_max(fks_configs),
3986- & cBW_FKS(fks_configs,-nexternal:-1),
3987- & cBW_FKS_level(fks_configs,-nexternal:-1)
3988- double precision cBW_FKS_mass(fks_configs,-1:1,-nexternal:-1),
3989- & cBW_FKS_width(fks_configs,-1:1,-nexternal:-1)
3990+ integer cBW_FKS_level_max(fks_configs,maxchannels),
3991+ & cBW_FKS(fks_configs,-nexternal:-1,maxchannels),
3992+ & cBW_FKS_level(fks_configs,-nexternal:-1,maxchannels)
3993+ double precision cBW_FKS_mass(fks_configs,-1:1,-nexternal:-1
3994+ $ ,maxchannels),cBW_FKS_width(fks_configs,-1:1,-nexternal:-1
3995+ $ ,maxchannels)
3996 save cBW_FKS_level_max,cBW_FKS,cBW_FKS_level,cBW_FKS_mass
3997 $ ,cBW_FKS_width
3998 integer cBW_level_max,cBW(-nexternal:-1),cBW_level(-nexternal:-1)
3999@@ -183,7 +186,7 @@
4000 common/c_conflictingBW/cBW_mass,cBW_width,cBW_level_max,cBW
4001 $ ,cBW_level
4002 double precision s_mass(-nexternal:nexternal)
4003- $ ,s_mass_FKS(fks_configs,-nexternal:nexternal)
4004+ $ ,s_mass_FKS(fks_configs,-nexternal:nexternal,maxchannels)
4005 save s_mass_FKS
4006 common/to_phase_space_s_channel/s_mass
4007 c Les Houches common block
4008@@ -192,18 +195,19 @@
4009 integer idup(nexternal,maxproc),mothup(2,nexternal,maxproc),
4010 & icolup(2,nexternal,maxflow),niprocs
4011 common /c_leshouche_inc/idup,mothup,icolup,niprocs
4012-c
4013 real*8 emass(nexternal)
4014 common/to_mass/emass
4015- logical firsttime
4016+ logical firsttime,firsttime_chans(maxchannels)
4017 data firsttime /.true./
4018+ data firsttime_chans/maxchannels*.true./
4019 if (firsttime) then
4020 do i = 1,lmaxconfigs
4021 do j = -nexternal,0
4022 pmass(j,i) = 0d0
4023 pwidth(j,i) = 0d0
4024- end do
4025- end do
4026+ enddo
4027+ enddo
4028+ firsttime=.false.
4029 endif
4030 include "born_props.inc"
4031
4032@@ -221,29 +225,29 @@
4033 c not necessarily the softest. Therefore, it could be that even though
4034 c the Born does not have enough energy to pass the cuts set by ptj, the
4035 c event could.
4036- if (firsttime) then
4037+ if (firsttime_chans(ichan)) then
4038 do i=-nexternal,nexternal
4039 xm(i)=0d0
4040 xw(i)=0d0
4041 mass_min(i)=0d0
4042 end do
4043- firsttime=.false.
4044+ firsttime_chans(ichan)=.false.
4045 do iFKS=1,fks_configs
4046 j_fks=FKS_J_D(iFKS)
4047- taumin(iFKS)=0.d0
4048- taumin_s(iFKS)=0.d0
4049- taumin_j(iFKS)=0.d0
4050+ taumin(iFKS,ichan)=0.d0
4051+ taumin_s(iFKS,ichan)=0.d0
4052+ taumin_j(iFKS,ichan)=0.d0
4053 do i=nincoming+1,nexternal
4054 c Add the minimal jet pTs to tau
4055 if(IS_A_J(i) .and. i.ne.nexternal)then
4056 if (j_fks.gt.nincoming .and. j_fks.lt.nexternal) then
4057- taumin(iFKS)=taumin(iFKS)+max(ptj,emass(i))
4058- taumin_s(iFKS)=taumin_s(iFKS)+max(ptj,emass(i))
4059- taumin_j(iFKS)=taumin_j(iFKS)+max(ptj,emass(i))
4060+ taumin(iFKS,ichan)=taumin(iFKS,ichan)+max(ptj,emass(i))
4061+ taumin_s(iFKS,ichan)=taumin_s(iFKS,ichan)+max(ptj,emass(i))
4062+ taumin_j(iFKS,ichan)=taumin_j(iFKS,ichan)+max(ptj,emass(i))
4063 elseif (j_fks.ge.1 .and. j_fks.le.nincoming) then
4064- taumin(iFKS)=taumin(iFKS)+emass(i)
4065- taumin_s(iFKS)=taumin_s(iFKS)+max(ptj,emass(i))
4066- taumin_j(iFKS)=taumin_j(iFKS)+max(ptj,emass(i))
4067+ taumin(iFKS,ichan)=taumin(iFKS,ichan)+emass(i)
4068+ taumin_s(iFKS,ichan)=taumin_s(iFKS,ichan)+max(ptj,emass(i))
4069+ taumin_j(iFKS,ichan)=taumin_j(iFKS,ichan)+max(ptj,emass(i))
4070 elseif (j_fks.eq.nexternal) then
4071 write (*,*)
4072 & 'ERROR, j_fks cannot be the final parton'
4073@@ -264,17 +268,17 @@
4074 stop
4075 endif
4076 if (j_fks.gt.nincoming)
4077- & taumin(iFKS)=taumin(iFKS)+ptgmin
4078- taumin_s(iFKS)=taumin_s(iFKS)+ptgmin
4079- taumin_j(iFKS)=taumin_j(iFKS)+ptgmin
4080+ & taumin(iFKS,ichan)=taumin(iFKS,ichan)+ptgmin
4081+ taumin_s(iFKS,ichan)=taumin_s(iFKS,ichan)+ptgmin
4082+ taumin_j(iFKS,ichan)=taumin_j(iFKS,ichan)+ptgmin
4083 xm(i)=emass(i)+ptgmin
4084 elseif (is_a_lp(i)) then
4085 c Add the postively charged lepton pTs to tau
4086- taumin(iFKS)=taumin(iFKS)+emass(i)
4087+ taumin(iFKS,ichan)=taumin(iFKS,ichan)+emass(i)
4088 if (j_fks.gt.nincoming)
4089- & taumin(iFKS)=taumin(iFKS)+ptl
4090- taumin_s(iFKS)=taumin_s(iFKS)+emass(i)+ptl
4091- taumin_j(iFKS)=taumin_j(iFKS)+emass(i)+ptl
4092+ & taumin(iFKS,ichan)=taumin(iFKS,ichan)+ptl
4093+ taumin_s(iFKS,ichan)=taumin_s(iFKS,ichan)+emass(i)+ptl
4094+ taumin_j(iFKS,ichan)=taumin_j(iFKS,ichan)+emass(i)+ptl
4095 xm(i)=emass(i)+ptl
4096 c Add the lepton invariant mass to tau if there is at least another
4097 c lepton of opposite charge. (Only add half of it, i.e. 'the part
4098@@ -284,22 +288,22 @@
4099 if (is_a_lm(j) .and. idup(i,1).eq.-idup(j,1) .and.
4100 $ (mll_sf.ne.0d0 .or. mll.ne.0d0) ) then
4101 if (j_fks.gt.nincoming)
4102- & taumin(iFKS) = taumin(iFKS)-ptl-emass(i) +
4103+ & taumin(iFKS,ichan) = taumin(iFKS,ichan)-ptl-emass(i) +
4104 & max(mll/2d0,mll_sf/2d0,ptl+emass(i))
4105- taumin_s(iFKS) = taumin_s(iFKS)-ptl-emass(i)
4106+ taumin_s(iFKS,ichan) = taumin_s(iFKS,ichan)-ptl-emass(i)
4107 $ + max(mll/2d0,mll_sf/2d0,ptl+emass(i))
4108- taumin_j(iFKS) = taumin_j(iFKS)-ptl-emass(i)
4109+ taumin_j(iFKS,ichan) = taumin_j(iFKS,ichan)-ptl-emass(i)
4110 $ + max(mll/2d0,mll_sf/2d0,ptl+emass(i))
4111 xm(i)=xm(i)-ptl-emass(i)+max(mll/2d0,mll_sf/2d0
4112 $ ,ptl+emass(i))
4113 exit
4114 elseif (is_a_lm(j) .and. mll.ne.0d0) then
4115 if (j_fks.gt.nincoming)
4116- & taumin(iFKS)= taumin(iFKS)-ptl-emass(i) +
4117+ & taumin(iFKS,ichan)= taumin(iFKS,ichan)-ptl-emass(i) +
4118 & max(mll/2d0,ptl+emass(i))
4119- taumin_s(iFKS) = taumin_s(iFKS)-ptl-emass(i)
4120+ taumin_s(iFKS,ichan) = taumin_s(iFKS,ichan)-ptl-emass(i)
4121 $ + max(mll/2d0,ptl+emass(i))
4122- taumin_j(iFKS) = taumin_j(iFKS)-ptl-emass(i)
4123+ taumin_j(iFKS,ichan) = taumin_j(iFKS,ichan)-ptl-emass(i)
4124 $ + max(mll/2d0,ptl+emass(i))
4125 xm(i)=xm(i)-ptl-emass(i)+max(mll/2d0,ptl
4126 $ +emass(i))
4127@@ -308,11 +312,11 @@
4128 enddo
4129 elseif (is_a_lm(i)) then
4130 c Add the negatively charged lepton pTs to tau
4131- taumin(iFKS)=taumin(iFKS)+emass(i)
4132+ taumin(iFKS,ichan)=taumin(iFKS,ichan)+emass(i)
4133 if (j_fks.gt.nincoming)
4134- & taumin(iFKS)=taumin(iFKS)+ptl
4135- taumin_s(iFKS)=taumin_s(iFKS)+emass(i)+ptl
4136- taumin_j(iFKS)=taumin_j(iFKS)+emass(i)+ptl
4137+ & taumin(iFKS,ichan)=taumin(iFKS,ichan)+ptl
4138+ taumin_s(iFKS,ichan)=taumin_s(iFKS,ichan)+emass(i)+ptl
4139+ taumin_j(iFKS,ichan)=taumin_j(iFKS,ichan)+emass(i)+ptl
4140 xm(i)=emass(i)+ptl
4141 c Add the lepton invariant mass to tau if there is at least another
4142 c lepton of opposite charge. (Only add half of it, i.e. 'the part
4143@@ -322,22 +326,22 @@
4144 if (is_a_lp(j) .and. idup(i,1).eq.-idup(j,1) .and.
4145 $ (mll_sf.ne.0d0 .or. mll.ne.0d0) ) then
4146 if (j_fks.gt.nincoming)
4147- & taumin(iFKS) = taumin(iFKS)-ptl-emass(i) +
4148+ & taumin(iFKS,ichan) = taumin(iFKS,ichan)-ptl-emass(i) +
4149 & max(mll/2d0,mll_sf/2d0,ptl+emass(i))
4150- taumin_s(iFKS) = taumin_s(iFKS)-ptl-emass(i)
4151+ taumin_s(iFKS,ichan) = taumin_s(iFKS,ichan)-ptl-emass(i)
4152 $ + max(mll/2d0,mll_sf/2d0,ptl+emass(i))
4153- taumin_j(iFKS) = taumin_j(iFKS)-ptl-emass(i)
4154+ taumin_j(iFKS,ichan) = taumin_j(iFKS,ichan)-ptl-emass(i)
4155 $ + max(mll/2d0,mll_sf/2d0,ptl+emass(i))
4156 xm(i)=xm(i)-ptl-emass(i)+max(mll/2d0,mll_sf/2d0
4157 $ ,ptl+emass(i))
4158 exit
4159 elseif (is_a_lp(j) .and. mll.ne.0d0) then
4160 if (j_fks.gt.nincoming)
4161- & taumin(iFKS) = taumin(iFKS)-ptl-emass(i) +
4162+ & taumin(iFKS,ichan) = taumin(iFKS,ichan)-ptl-emass(i) +
4163 & max(mll/2d0,ptl+emass(i))
4164- taumin_s(iFKS) = taumin_s(iFKS)-ptl-emass(i)
4165+ taumin_s(iFKS,ichan) = taumin_s(iFKS,ichan)-ptl-emass(i)
4166 $ + max(mll/2d0,ptl+emass(i))
4167- taumin_j(iFKS) = taumin_j(iFKS)-ptl-emass(i)
4168+ taumin_j(iFKS,ichan) = taumin_j(iFKS,ichan)-ptl-emass(i)
4169 $ + max(mll/2d0,ptl+emass(i))
4170 xm(i)=xm(i)-ptl-emass(i)+max(mll/2d0,ptl
4171 $ +emass(i))
4172@@ -345,16 +349,16 @@
4173 endif
4174 enddo
4175 else
4176- taumin(iFKS)=taumin(iFKS)+emass(i)
4177- taumin_s(iFKS)=taumin_s(iFKS)+emass(i)
4178- taumin_j(iFKS)=taumin_j(iFKS)+emass(i)
4179+ taumin(iFKS,ichan)=taumin(iFKS,ichan)+emass(i)
4180+ taumin_s(iFKS,ichan)=taumin_s(iFKS,ichan)+emass(i)
4181+ taumin_j(iFKS,ichan)=taumin_j(iFKS,ichan)+emass(i)
4182 xm(i)=emass(i)
4183 endif
4184 xw(i)=0d0
4185 enddo
4186 stot = 4d0*ebeam(1)*ebeam(2)
4187- tau_Born_lower_bound=taumin(iFKS)**2/stot
4188- tau_lower_bound=taumin_j(iFKS)**2/stot
4189+ tau_Born_lower_bound=taumin(iFKS,ichan)**2/stot
4190+ tau_lower_bound=taumin_j(iFKS,ichan)**2/stot
4191 c
4192 c Also find the minimum lower bound if all internal s-channel particles
4193 c were on-shell
4194@@ -373,9 +377,9 @@
4195 xw1=xw(d1)
4196 xw2=xw(d2)
4197 c On-shell mass of the intermediate resonance
4198- xmi=pmass(i,iconfig)
4199+ xmi=pmass(i,iconf)
4200 c Width of the intermediate resonance
4201- xwi=pwidth(i,iconfig)
4202+ xwi=pwidth(i,iconf)
4203 c Set the intermediate mass equal to the max of its actual mass and
4204 c the sum of the masses of the two daugters.
4205 if (xmi.gt.xm1+xm2) then
4206@@ -388,7 +392,7 @@
4207 c Add the new mass to the bound. To avoid double counting, we should
4208 c subtract the daughters, because they are already included above or in
4209 c the previous iteration of the loop
4210- taumin_s(iFKS)=taumin_s(iFKS)+xm(i)-xm1-xm2
4211+ taumin_s(iFKS,ichan)=taumin_s(iFKS,ichan)+xm(i)-xm1-xm2
4212 else ! t-channels
4213 if (i.eq.-(nexternal-3)) then
4214 xm(i)=0d0
4215@@ -409,10 +413,10 @@
4216 cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
4217 c Determine the "minimal" s-channel invariant masses
4218 do i=nincoming+1,nexternal-1
4219- s_mass_FKS(iFKS,i)=xm(i)**2
4220+ s_mass_FKS(iFKS,i,ichan)=xm(i)**2
4221 enddo
4222 do i=-1,-(nexternal-3),-1 ! All propagators
4223- s_mass_FKS(iFKS,i)=xm(i)**2
4224+ s_mass_FKS(iFKS,i,ichan)=xm(i)**2
4225 enddo
4226 cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
4227 c Determine the conflicting Breit-Wigner's. Note that xm(i) contains the
4228@@ -420,13 +424,13 @@
4229 do i=nincoming+1,nexternal-1
4230 mass_min(i)=xm(i) ! minimal allowed resonance mass (including masses set by cuts)
4231 enddo
4232- cBW_FKS_level_max(iFKS)=0
4233+ cBW_FKS_level_max(iFKS,ichan)=0
4234 t_channel=0
4235 do i=-1,-(nexternal-3),-1 ! All propagators
4236- cBW_FKS_mass(iFKS,1,i)=0d0
4237- cBW_FKS_width(iFKS,1,i)=0d0
4238- cBW_FKS_mass(iFKS,-1,i)=0d0
4239- cBW_FKS_width(iFKS,-1,i)=0d0
4240+ cBW_FKS_mass(iFKS,1,i,ichan)=0d0
4241+ cBW_FKS_width(iFKS,1,i,ichan)=0d0
4242+ cBW_FKS_mass(iFKS,-1,i,ichan)=0d0
4243+ cBW_FKS_width(iFKS,-1,i,ichan)=0d0
4244 masslow(i)=9d99
4245 widthlow(i)=0d0
4246 if ( itree(1,i).eq.1 .or. itree(1,i).eq.2 ) t_channel=i
4247@@ -438,39 +442,39 @@
4248 $ ,xm(i),mass_min(i)
4249 stop
4250 endif
4251- if (pmass(i,iconfig).lt.xm(i) .and.
4252- $ pwidth(i,iconfig).gt.0d0) then
4253+ if (pmass(i,iconf).lt.xm(i) .and.
4254+ $ pwidth(i,iconf).gt.0d0) then
4255 c Possible conflict in BW
4256- if (pmass(i,iconfig).lt.mass_min(i)) then
4257+ if (pmass(i,iconf).lt.mass_min(i)) then
4258 c Resonance can never go on-shell due to the kinematics of the event
4259- cBW_FKS(iFKS,i)=2
4260- cBW_FKS_level(iFKS,i)=0
4261- elseif(pmass(i,iconfig).lt.xm(i)) then
4262+ cBW_FKS(iFKS,i,ichan)=2
4263+ cBW_FKS_level(iFKS,i,ichan)=0
4264+ elseif(pmass(i,iconf).lt.xm(i)) then
4265 c Conflicting Breit-Wigner
4266- cBW_FKS(iFKS,i)=1
4267- cBW_FKS_level(iFKS,i)=1
4268- cBW_FKS_level_max(iFKS)=max(cBW_FKS_level_max(iFKS)
4269- $ ,cBW_FKS_level(iFKS,i))
4270+ cBW_FKS(iFKS,i,ichan)=1
4271+ cBW_FKS_level(iFKS,i,ichan)=1
4272+ cBW_FKS_level_max(iFKS,ichan)=max(cBW_FKS_level_max(iFKS,ichan)
4273+ $ ,cBW_FKS_level(iFKS,i,ichan))
4274 c Set here the mass (and width) of the alternative mass; it's the
4275 c sum of daughter masses. (2nd argument is '1', because this
4276 c alternative mass is LARGER than the resonance mass).
4277- cBW_FKS_mass(iFKS,1,i)=xm(i)
4278- cBW_FKS_width(iFKS,1,i)=xw(i)
4279+ cBW_FKS_mass(iFKS,1,i,ichan)=xm(i)
4280+ cBW_FKS_width(iFKS,1,i,ichan)=xw(i)
4281 endif
4282 c set the daughters also as conflicting (recursively)
4283- masslow(i)=pmass(i,iconfig)
4284- widthlow(i)=pwidth(i,iconfig)
4285+ masslow(i)=pmass(i,iconf)
4286+ widthlow(i)=pwidth(i,iconf)
4287 do j=i,-1
4288- if (cBW_FKS(iFKS,j).eq.0) cycle
4289+ if (cBW_FKS(iFKS,j,ichan).eq.0) cycle
4290 do k=1,2 ! loop over the 2 daughters
4291 if (itree(k,j).ge.0) cycle
4292- if (cBW_FKS(iFKS,itree(k,j)).eq.2) cycle
4293- cBW_FKS(iFKS,itree(k,j))=1
4294- cBW_FKS_level(iFKS,itree(k,j))=
4295- $ cBW_FKS_level(iFKS,j)+1
4296- cBW_FKS_level_max(iFKS)=
4297- $ max(cBW_FKS_level_max(iFKS)
4298- $ ,cBW_FKS_level(iFKS,itree(k,j)))
4299+ if (cBW_FKS(iFKS,itree(k,j),ichan).eq.2) cycle
4300+ cBW_FKS(iFKS,itree(k,j),ichan)=1
4301+ cBW_FKS_level(iFKS,itree(k,j),ichan)=
4302+ $ cBW_FKS_level(iFKS,j,ichan)+1
4303+ cBW_FKS_level_max(iFKS,ichan)=
4304+ $ max(cBW_FKS_level_max(iFKS,ichan)
4305+ $ ,cBW_FKS_level(iFKS,itree(k,j),ichan))
4306 c Set here the mass (and width) of the alternative mass; it's the
4307 c difference between the mother and the sister masses. (3rd argument
4308 c is '-1', because this alternative mass is SMALLER than the
4309@@ -479,18 +483,18 @@
4310 & max(masslow(j)-xm(itree(3-k,j)),0d0)) ! mass difference
4311 widthlow(itree(k,j))=max(widthlow(itree(k,j)),
4312 & widthlow(j)+xw(itree(3-k,j))) ! sum of widths
4313- if (pwidth(itree(k,j),iconfig).eq.0d0 .or.
4314+ if (pwidth(itree(k,j),iconf).eq.0d0 .or.
4315 $ masslow(itree(k,j)).ge.pmass(itree(k,j)
4316- $ ,iconfig)) cycle
4317- cBW_FKS_mass(iFKS,-1,itree(k,j))=
4318+ $ ,iconf)) cycle
4319+ cBW_FKS_mass(iFKS,-1,itree(k,j),ichan)=
4320 $ masslow(itree(k,j))
4321- cBW_FKS_width(iFKS,-1,itree(k,j))=
4322+ cBW_FKS_width(iFKS,-1,itree(k,j),ichan)=
4323 $ widthlow(itree(k,j))
4324 enddo
4325 enddo
4326 else
4327 c Normal Breit-Wigner
4328- cBW_FKS(iFKS,i)=0
4329+ cBW_FKS(iFKS,i,ichan)=0
4330 endif
4331 enddo
4332 c loop over t-channel to make sure that s-hat is consistent with sum of
4333@@ -500,9 +504,9 @@
4334 do i=t_channel,-(nexternal-3),-1
4335 c Breit-wigner can never go on-shell:
4336 if (itree(2,i).gt.0) cycle
4337- if ( pmass(itree(2,i),iconfig).gt.sqrt(stot) .and.
4338- $ pwidth(itree(2,i),iconfig).gt.0d0) then
4339- cBW_FKS(iFKS,itree(2,i))=2
4340+ if ( pmass(itree(2,i),iconf).gt.sqrt(stot) .and.
4341+ $ pwidth(itree(2,i),iconf).gt.0d0) then
4342+ cBW_FKS(iFKS,itree(2,i),ichan)=2
4343 endif
4344 c s-channel is always 2nd argument of itree, sum it to sum_all_s
4345 sum_all_s=sum_all_s+xm(itree(2,i))
4346@@ -511,10 +515,10 @@
4347 c conflicting BWs: set all s-channels as conflicting
4348 do i=t_channel,-(nexternal-3),-1
4349 if (itree(2,i).gt.0) cycle
4350- if (cBW_FKS(iFKS,itree(2,i)).ne.2) then
4351- cBW_FKS(iFKS,itree(2,i))=1
4352- cBW_FKS_mass(iFKS,-1,itree(2,i))=sqrt(stot)/2d0
4353- cBW_FKS_width(iFKS,-1,itree(2,i))=xw(itree(2,i))
4354+ if (cBW_FKS(iFKS,itree(2,i),ichan).ne.2) then
4355+ cBW_FKS(iFKS,itree(2,i),ichan)=1
4356+ cBW_FKS_mass(iFKS,-1,itree(2,i),ichan)=sqrt(stot)/2d0
4357+ cBW_FKS_width(iFKS,-1,itree(2,i),ichan)=xw(itree(2,i))
4358 endif
4359 enddo
4360 endif
4361@@ -526,41 +530,38 @@
4362 c
4363 c If the lower bound found here is smaller than the hard bound,
4364 c simply set the soft bound equal to the hard bound.
4365- taumin_s(iFKS)=
4366- & max(taumin_j(iFKS),taumin_s(iFKS))
4367+ taumin_s(iFKS,ichan)=
4368+ & max(taumin_j(iFKS,ichan),taumin_s(iFKS,ichan))
4369 c
4370 c For the bound, we have to square and divide by stot.
4371- tau_lower_bound_resonance=taumin_s(iFKS)**2/stot
4372+ tau_lower_bound_resonance=taumin_s(iFKS,ichan)**2/stot
4373 c
4374- write (*,'(a,i3,a,3(e12.5,x))') 'nFKSprocess:',iFKS
4375- & ,'. Absolute lower bound for tau at the Born is'
4376- & ,tau_Born_lower_bound,taumin(iFKS),dsqrt(stot)
4377- if (j_fks.le.nincoming) then
4378- write (*,'(a,i3,a,3(e12.5,x))') 'nFKSprocess:',iFKS
4379- & ,'. Lower bound for tau is',tau_lower_bound
4380- & ,taumin_j(iFKS),dsqrt(stot)
4381+ if (j_fks.gt.nincoming) then
4382+ write (*,'(a7,x,i3,x,i5,x,a1,3(e12.5,x)))') 'tau_min'
4383+ $ ,iFKS,ichan,':',taumin(iFKS,ichan),taumin_j(iFKS
4384+ $ ,ichan),taumin_s(iFKS,ichan)
4385+ else
4386+ write (*,'(a7,x,i3,x,i5,x,a1,e12.5,x,a13,e12.5,x))')
4387+ $ 'tau_min',iFKS,ichan,':',taumin(iFKS,ichan)
4388+ $ ,' -- ',taumin_s(iFKS,ichan)
4389 endif
4390- write (*,'(a,i3,a,3(e12.5,x))') 'nFKSprocess:',iFKS
4391- & ,'. Lower bound for tau is (taking resonances'/
4392- & /' into account)' ,tau_lower_bound_resonance
4393- & ,taumin_s(iFKS) ,dsqrt(stot)
4394 enddo
4395 endif
4396- tau_Born_lower_bound=taumin(nFKSprocess)**2/stot
4397- tau_lower_bound=taumin_j(nFKSprocess)**2/stot
4398- tau_lower_bound_resonance=taumin_s(nFKSprocess)**2/stot
4399+ tau_Born_lower_bound=taumin(nFKSprocess,ichan)**2/stot
4400+ tau_lower_bound=taumin_j(nFKSprocess,ichan)**2/stot
4401+ tau_lower_bound_resonance=taumin_s(nFKSprocess,ichan)**2/stot
4402 do i=-nexternal,-1
4403- cBW(i)=cBW_FKS(nFKSprocess,i)
4404- cBW_level(i)=cBW_FKS_level(nFKSprocess,i)
4405+ cBW(i)=cBW_FKS(nFKSprocess,i,ichan)
4406+ cBW_level(i)=cBW_FKS_level(nFKSprocess,i,ichan)
4407 do j=-1,1,2
4408- cBW_mass(j,i)=cBW_FKS_mass(nFKSprocess,j,i)
4409- cBW_width(j,i)=cBW_FKS_width(nFKSprocess,j,i)
4410+ cBW_mass(j,i)=cBW_FKS_mass(nFKSprocess,j,i,ichan)
4411+ cBW_width(j,i)=cBW_FKS_width(nFKSprocess,j,i,ichan)
4412 enddo
4413 enddo
4414 do i=-nexternal,nexternal
4415- s_mass(i)=s_mass_FKS(nFKSprocess,i)
4416+ s_mass(i)=s_mass_FKS(nFKSprocess,i,ichan)
4417 enddo
4418- cBW_level_max=cBW_FKS_level_max(nFKSprocess)
4419+ cBW_level_max=cBW_FKS_level_max(nFKSprocess,ichan)
4420 return
4421 end
4422
4423@@ -574,8 +575,8 @@
4424 double precision pmass(-nexternal:0,lmaxconfigs)
4425 double precision pwidth(-nexternal:0,lmaxconfigs)
4426 integer pow(-nexternal:0,lmaxconfigs)
4427- integer itree(2,-max_branch:-1),iconfig
4428- common /to_itree/itree,iconfig
4429+ integer itree(2,-max_branch:-1),iconf
4430+ common /to_itree/itree,iconf
4431 logical new_point
4432 common /c_new_point/new_point
4433 double precision ran2,rnd
4434
4435=== modified file 'Template/NLO/SubProcesses/symmetry_fks_test_MC.f'
4436--- Template/NLO/SubProcesses/symmetry_fks_test_MC.f 2016-09-27 15:07:53 +0000
4437+++ Template/NLO/SubProcesses/symmetry_fks_test_MC.f 2017-03-08 10:27:27 +0000
4438@@ -14,6 +14,7 @@
4439 include 'fks_info.inc'
4440 include 'run.inc'
4441 include 'cuts.inc'
4442+ include 'mint.inc'
4443
4444 double precision ZERO,one
4445 parameter (ZERO = 0d0)
4446@@ -68,7 +69,7 @@
4447 double precision p(0:3,99), wgt, x(99), fx
4448 double complex wgt1(2)
4449 double precision p1(0:3,99),xx(maxinvar)
4450- integer ninvar, ndim, iconfig, minconfig, maxconfig
4451+ integer ninvar, ndim, minconfig, maxconfig
4452 common/tosigint/ndim
4453 integer ncall,itmax,nconfigs,ntry, ngraphs
4454 integer ic(nexternal,maxswitch), jc(12),nswitch
4455@@ -333,7 +334,9 @@
4456 endif
4457
4458 do iconfig=bs_min,bs_max ! Born configurations
4459-
4460+ ichan=1
4461+ iconfigs(1)=iconfig
4462+
4463 call set_mc_matrices
4464
4465 wgt=1d0
4466
4467=== modified file 'Template/NLO/SubProcesses/symmetry_fks_test_ME.f'
4468--- Template/NLO/SubProcesses/symmetry_fks_test_ME.f 2016-09-27 15:07:53 +0000
4469+++ Template/NLO/SubProcesses/symmetry_fks_test_ME.f 2017-03-08 10:27:27 +0000
4470@@ -14,6 +14,7 @@
4471 include 'fks_info.inc'
4472 include 'run.inc'
4473 include 'cuts.inc'
4474+ include 'mint.inc'
4475
4476 double precision ZERO,one
4477 parameter (ZERO = 0d0)
4478@@ -59,7 +60,7 @@
4479 double precision p(0:3,99), wgt, x(99), fx
4480 double complex wgt1(2)
4481 double precision p1(0:3,99),xx(maxinvar)
4482- integer ninvar, ndim, iconfig, minconfig, maxconfig
4483+ integer ninvar, ndim, minconfig, maxconfig
4484 common/tosigint/ndim
4485 integer ncall,itmax,nconfigs,ntry, ngraphs
4486 integer ic(nexternal,maxswitch), jc(12),nswitch
4487@@ -279,7 +280,9 @@
4488 bs_max=iconfig_in
4489 endif
4490
4491- do iconfig=bs_min,bs_max ! Born configurations
4492+ do iconfig=bs_min,bs_max ! Born configurations
4493+ ichan=1
4494+ iconfigs(1)=iconfig
4495 call setcuts
4496 call setfksfactor(iconfig,.false.)
4497 wgt=1d0
4498
4499=== modified file 'Template/NLO/SubProcesses/symmetry_fks_v3.f'
4500--- Template/NLO/SubProcesses/symmetry_fks_v3.f 2016-09-27 15:07:53 +0000
4501+++ Template/NLO/SubProcesses/symmetry_fks_v3.f 2017-03-08 10:27:27 +0000
4502@@ -10,6 +10,7 @@
4503 include 'genps.inc'
4504 include 'nexternal.inc'
4505 include '../../Source/run_config.inc'
4506+ include 'mint.inc'
4507
4508 double precision ZERO
4509 parameter (ZERO = 0d0)
4510@@ -49,7 +50,7 @@
4511 & -1),p_ev_red_save(0:3,nexternal-1)
4512 double precision p1_cnt_save(0:3,nexternal,-2:2),p_born_save(0:3
4513 & ,nexternal-1),p_ev_red1(0:3,nexternal-1)
4514- integer ninvar, ndim, iconfig, minconfig, maxconfig
4515+ integer ninvar, ndim, minconfig, maxconfig
4516 common/tosigint/ndim
4517 integer ncall,itmax,nconfigs,ntry, ngraphs
4518 integer icb(nexternal-1,maxswitch),jc(12),nswitch
4519@@ -180,6 +181,8 @@
4520 call printout
4521 call run_printout
4522 iconfig=1
4523+ ichan=1
4524+ iconfigs(1)=iconfig
4525 call setfksfactor(iconfig,.false.)
4526 c
4527 ndim = 55
4528
4529=== modified file 'Template/NLO/SubProcesses/write_event.f'
4530--- Template/NLO/SubProcesses/write_event.f 2016-05-13 12:40:54 +0000
4531+++ Template/NLO/SubProcesses/write_event.f 2017-03-08 10:27:27 +0000
4532@@ -5,16 +5,14 @@
4533 include "unlops.inc"
4534 include "run.inc"
4535 include 'timing_variables.inc'
4536+ include 'mint.inc'
4537 integer ndim
4538 common/tosigint/ndim
4539- integer iconfig
4540- common/to_configs/iconfig
4541 integer itmax,ncall
4542 common/citmax/itmax,ncall
4543 logical Hevents
4544 common/SHevents/Hevents
4545 integer i,j,lunlhe
4546- include 'mint.inc'
4547 real*8 xx(ndimmax),weight,evnt_wgt
4548 logical putonshell
4549 double precision wgt,unwgtfun
4550@@ -263,7 +261,7 @@
4551 write(*,*)doreweight,iwgtinfo
4552 stop
4553 endif
4554- kwgtinfo=iwgtinfo
4555+ kwgtinfo= iwgtinfo
4556 write(buff,201)'#aMCatNLO',iSorH_lhe,ifks_lhe(nFKSprocess)
4557 & ,jfks_lhe(nFKSprocess),fksfather_lhe(nFKSprocess)
4558 & ,ipartner_lhe(nFKSprocess),scale1_lhe(nFKSprocess)
4559
4560=== modified file 'Template/loop_material/StandAlone/SubProcesses/makefile'
4561--- Template/loop_material/StandAlone/SubProcesses/makefile 2016-06-24 18:12:15 +0000
4562+++ Template/loop_material/StandAlone/SubProcesses/makefile 2017-03-08 10:27:27 +0000
4563@@ -81,9 +81,11 @@
4564 # This is the core of madloop computationally wise, so make sure to turn optimizations on and bound checks off.
4565 # We use %olynomial.o and not directly polynomial.o because we want it to match when both doing make check here
4566 # or make OLP one directory above
4567+%oloop_matrix.o : %olynomial.o %oloop_matrix.f
4568 %olynomial.o : %olynomial.f
4569 $(FC) $(patsubst -O%,, $(subst -fbounds-check,,$(FFLAGS))) $(POLYNOMIAL_OPTIMIZATION) $(POLYNOMIAL_BOUNDS_CHECK) -c $< -o $@ $(LOOP_INCLUDE)
4570
4571+
4572 $(DOTO) : $(DOTF)
4573 $(FC) $(FFLAGS) -c $< -o $@ $(LOOP_INCLUDE)
4574
4575
4576=== modified file 'UpdateNotes.txt'
4577--- UpdateNotes.txt 2016-12-10 02:08:09 +0000
4578+++ UpdateNotes.txt 2017-03-08 10:27:27 +0000
4579@@ -1,5 +1,25 @@
4580 Update notes for MadGraph5_aMC@NLO (in reverse time order)
4581
4582+2.5.3(XX/XX/17)
4583+ PT: Modified the default shower starting scale in montecarlocounter.f.
4584+ The new reference scale from which the dampening profile is computed is sum_i mt_i/2, i
4585+ being Born level final-state momenta.
4586+ OM: New "special mode" for madspin accessible via "set spinmode onshell".
4587+ This mode allow for full spin-correlation with 3 (or more) body decay but the decaying particle
4588+ remains exactly onshell in this mode. Loop-induced production/decay are not allowed in this mode.
4589+ OM+RF: Allowing for creation of LHE like output of the fixed order run at NLO.
4590+ This LHEF file is unvalid for parton-shower (all PS should crash on such file). It will be
4591+ unphysical to shower such sample anyway.
4592+ Two hidden parameters of the FO_analyse_card.dat allow some control on the LHEF creation
4593+ "fo_lhe_weight_ratio" allows to control the strength of a partial unweighting [default:1e-3]
4594+ increasing this number reduce the LHEF size.
4595+ "fo_lhe_postprocessing" can take value like nogrouping, norandom, noidentification.
4596+ nogrouping forbids the appearance of the LHEF(version2) tag <eventgroup>
4597+ norandom does not apply the randomization of the events.
4598+ noidentification does not merge born event with other born like counter-event
4599+ RF: Better job handling for fNLO runs.
4600+ VH: Fixing various problem with the pythia8 interface (especially for MLM merging)
4601+
4602 2.5.2(10/12/16)
4603 OM: improve systematics (thanks to Philipp Pigard)
4604 OM: new syntax to modify the run_card: set no_parton_cut
4605
4606=== modified file 'aloha/aloha_lib.py'
4607--- aloha/aloha_lib.py 2015-10-22 22:04:45 +0000
4608+++ aloha/aloha_lib.py 2017-03-08 10:27:27 +0000
4609@@ -50,6 +50,11 @@
4610 import re
4611 import aloha # define mode of writting
4612
4613+try:
4614+ import madgraph.various.misc as misc
4615+except Exception:
4616+ import aloha.misc as misc
4617+
4618 class defaultdict(collections.defaultdict):
4619
4620 def __call__(self, *args):
4621@@ -158,7 +163,6 @@
4622 # check if the function is a pure numerical function.
4623 if (fct_tag.startswith('cmath.') or fct_tag in self.known_fct) and \
4624 all(isinstance(x, numbers.Number) for x in argument):
4625- print "start the hack"
4626 import cmath
4627 if fct_tag.startswith('cmath.'):
4628 module = ''
4629@@ -1056,7 +1060,8 @@
4630 self.spin_ind = spin_indices #spin indices
4631 self.nb_spin = len(spin_indices) #their number
4632 self.nb_ind = self.nb_lor + self.nb_spin #total number of indices
4633-
4634+
4635+
4636 #store the representation
4637 if self.lorentz_ind or self.spin_ind:
4638 dict.__init__(self, representation)
4639
4640=== modified file 'aloha/aloha_parsers.py'
4641--- aloha/aloha_parsers.py 2015-10-01 16:00:08 +0000
4642+++ aloha/aloha_parsers.py 2017-03-08 10:27:27 +0000
4643@@ -36,6 +36,11 @@
4644 from aloha.aloha_lib import KERNEL
4645 logger = logging.getLogger('aloha.parsers')
4646
4647+try:
4648+ import madgraph.various.misc as misc
4649+except Exception:
4650+ import aloha.misc as misc
4651+
4652
4653 # PLY lexer class
4654 class UFOExpressionParser(object):
4655@@ -268,7 +273,6 @@
4656 if re_groups:
4657 p1 = re_groups.group("name")
4658 new = aloha_lib.KERNEL.add_function_expression(p1, eval(p[3]))
4659-
4660 p[0] = str(new)
4661
4662 def p_expression_function2(self, p):
4663
4664=== modified file 'aloha/create_aloha.py'
4665--- aloha/create_aloha.py 2016-04-15 11:14:25 +0000
4666+++ aloha/create_aloha.py 2017-03-08 10:27:27 +0000
4667@@ -211,9 +211,10 @@
4668 new_id = _conjugate_gap + old_id
4669
4670 self.kernel_tag = set()
4671- if not self.routine_kernel or isinstance(self.routine_kernel, str):
4672+ aloha_lib.KERNEL.use_tag = set()
4673+ if not self.routine_kernel or isinstance(self.routine_kernel, str):
4674 self.routine_kernel = eval(self.parse_expression(self.lorentz_expr))
4675-
4676+ self.kernel_tag = aloha_lib.KERNEL.use_tag
4677 # We need to compute C Gamma^T C^-1 = C_ab G_cb (-1) C_cd
4678 # = C_ac G_bc (-1) C_bd = C_ac G_bc C_db
4679 self.routine_kernel = \
4680@@ -399,7 +400,7 @@
4681
4682 if factorize:
4683 lorentz = lorentz.factorize()
4684-
4685+
4686 lorentz.tag = set(aloha_lib.KERNEL.use_tag)
4687 return lorentz
4688
4689
4690=== modified file 'bin/compile.py'
4691--- bin/compile.py 2015-06-24 12:55:44 +0000
4692+++ bin/compile.py 2017-03-08 10:27:27 +0000
4693@@ -17,6 +17,8 @@
4694 import sys
4695 import logging
4696 import time
4697+import shutil
4698+import subprocess
4699 # Get the parent directory (mg root) of the script real path (bin)
4700 # and add it to the current PYTHONPATH
4701 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
4702@@ -37,21 +39,44 @@
4703 pjoin = os.path.join
4704
4705 class Compile_MG5:
4706-
4707- def __init__(self):
4708+
4709+ autorun = True
4710+ overwrite_configuration=True
4711+
4712+ def __init__(self, ext_programs):
4713 """ launch all the compilation """
4714-
4715- self.make_UFO_pkl()
4716- self.make_v4_pkl()
4717- self.make_stdHep()
4718- self.make_CutTools()
4719- self.make_IREGI()
4720-
4721- #important for UCL cluster
4722- files.cp(pjoin(MG5DIR,'input','.mg5_configuration_default.txt'),
4723- pjoin(MG5DIR,'input','mg5_configuration.txt'))
4724- self.cmd = interface.MasterCmd()
4725- self.install_package()
4726+
4727+ # important to uclclus
4728+ if self.overwrite_configuration:
4729+ files.cp(pjoin(MG5DIR,'input','.mg5_configuration_default.txt'),
4730+ pjoin(MG5DIR,'input','mg5_configuration.txt'))
4731+
4732+ self.cmd = interface.MasterCmd()
4733+
4734+ if self.autorun:
4735+ self.make_UFO_pkl()
4736+ self.make_v4_pkl()
4737+ self.make_stdHep()
4738+ self.make_CutTools()
4739+ self.make_IREGI()
4740+ self.install_package(ext_programs)
4741+ self.test_output_LO()
4742+ self.test_output_NLO()
4743+ self.precompilation(debug=True)
4744+ self.precompilation(debug=False)
4745+
4746+
4747+ def test_output_LO(self):
4748+ """do the output of a simple LO process to ensure that LO is correctly configure."""
4749+ self.cmd.exec_cmd('generate p p > t t~')
4750+ self.cmd.exec_cmd('output %s/TESTLO' %root_path)
4751+ shutil.rmtree('%s/TESTLO' % root_path)
4752+
4753+ def test_output_NLO(self):
4754+ """do the output of a simple LO process to ensure that LO is correctly configure."""
4755+ self.cmd.exec_cmd('generate p p > e+ ve [QCD]')
4756+ self.cmd.exec_cmd('output %s/TESTNLO' %root_path)
4757+ shutil.rmtree('%s/TESTNLO' % root_path)
4758
4759 @staticmethod
4760 def make_v4_pkl():
4761@@ -250,13 +275,22 @@
4762
4763 misc.compile(cwd = os.path.join(iregi_path,'src'))
4764
4765- def install_package(self):
4766+ def install_package(self, programs=[]):
4767 print "installing external package"
4768- self.cmd.exec_cmd('install pythia-pgs')
4769- self.cmd.exec_cmd('install Delphes')
4770- self.cmd.exec_cmd('install ExRootAnalysis')
4771- self.cmd.exec_cmd('install MadAnalysis')
4772- self.cmd.exec_cmd('install SysCalc')
4773+ if not programs:
4774+ programs = ['pythia-pgs','Delphes','ExRootAnalysis','MadAnalysis4','SysCalc']
4775+
4776+ for prog in programs:
4777+ self.cmd.exec_cmd('install %s' % prog)
4778+
4779+ def precompilation(self, debug=False):
4780+ if debug:
4781+ subprocess.call('python -m compileall .', shell=True, cwd=root_path)
4782+ else:
4783+ subprocess.call('python -O -m compileall .', shell=True, cwd=root_path)
4784
4785 if __name__ == '__main__':
4786- Compile_MG5()
4787+ Compile_MG5(sys.argv[1:])
4788+
4789+
4790+
4791
4792=== modified file 'bin/create_release.py'
4793--- bin/create_release.py 2016-09-07 17:11:30 +0000
4794+++ bin/create_release.py 2017-03-08 10:27:27 +0000
4795@@ -176,7 +176,11 @@
4796 shutil.rmtree(path.join(filepath, '.bzr'))
4797 for data in glob.glob(path.join(filepath, 'bin', '*')):
4798 if not data.endswith('mg5') and not data.endswith('mg5_aMC'):
4799- os.remove(data)
4800+ if 'compile.py' not in data:
4801+ os.remove(data)
4802+ else:
4803+ os.rename(data, data.replace('compile.py','.compile.py'))
4804+
4805 os.remove(path.join(filepath, 'README.developer'))
4806 shutil.move(path.join(filepath, 'README.release'), path.join(filepath, 'README'))
4807
4808
4809=== modified file 'bin/mg5_aMC'
4810--- bin/mg5_aMC 2016-05-31 16:43:42 +0000
4811+++ bin/mg5_aMC 2017-03-08 10:27:27 +0000
4812@@ -1,4 +1,6 @@
4813 #! /usr/bin/env python
4814+import time
4815+start = time.time()
4816
4817 ################################################################################
4818 #
4819@@ -103,7 +105,6 @@
4820 if __debug__:
4821 print 'Running MG5 in debug mode'
4822
4823-
4824 # Set logging level according to the logging level given by options
4825 #logging.basicConfig(level=vars(logging)[options.logging])
4826 try:
4827@@ -120,8 +121,12 @@
4828 logging.getLogger('madevent').setLevel(level)
4829 except:
4830 pass
4831+
4832 import madgraph.interface.master_interface as interface
4833
4834+if __debug__ and time.time() - start > 0.5:
4835+ print 'WARNING: loading of madgraph too slow!!!', time.time() - start
4836+
4837 if options.plugin:
4838 if not os.path.exists(os.path.join(root_path, 'PLUGIN', options.plugin)):
4839 print "ERROR: %s is not present in the PLUGIN directory. Please install it first"
4840@@ -140,6 +145,8 @@
4841 else:
4842 cmd_line = interface.MasterCmd(mgme_dir = options.mgme_dir)
4843
4844+
4845+
4846 # Call the cmd interface main loop
4847 try:
4848 if options.file or args:
4849
4850=== modified file 'madgraph/core/base_objects.py'
4851--- madgraph/core/base_objects.py 2016-12-06 11:25:57 +0000
4852+++ madgraph/core/base_objects.py 2017-03-08 10:27:27 +0000
4853@@ -1223,6 +1223,10 @@
4854 self['order_hierarchy'] = {}
4855 self['expansion_order'] = None
4856
4857+ if name == 'name2pdg':
4858+ self['name2pgg'] = value
4859+ return
4860+
4861 result = Model.__bases__[0].set(self, name, value, force) # call the mother routine
4862
4863 if name == 'particles':
4864
4865=== modified file 'madgraph/core/diagram_generation.py'
4866--- madgraph/core/diagram_generation.py 2016-08-07 07:16:07 +0000
4867+++ madgraph/core/diagram_generation.py 2017-03-08 10:27:27 +0000
4868@@ -1333,7 +1333,7 @@
4869 self['decay_chains'] = DecayChainAmplitudeList()
4870
4871 def __init__(self, argument = None, collect_mirror_procs = False,
4872- ignore_six_quark_processes = False, loop_filter=None):
4873+ ignore_six_quark_processes = False, loop_filter=None, diagram_filter=False):
4874 """Allow initialization with Process and with ProcessDefinition"""
4875
4876 if isinstance(argument, base_objects.Process):
4877@@ -1348,11 +1348,13 @@
4878 MultiProcessClass.generate_multi_amplitudes(argument,
4879 collect_mirror_procs,
4880 ignore_six_quark_processes,
4881- loop_filter=loop_filter))
4882+ loop_filter=loop_filter,
4883+ diagram_filter=diagram_filter))
4884 else:
4885 self['amplitudes'].append(\
4886 MultiProcessClass.get_amplitude_from_proc(argument,
4887- loop_filter=loop_filter))
4888+ loop_filter=loop_filter,
4889+ diagram_filter=diagram_filter))
4890 # Clean decay chains from process, since we haven't
4891 # combined processes with decay chains yet
4892 process = copy.copy(self.get('amplitudes')[0].get('process'))
4893@@ -1630,7 +1632,8 @@
4894 self['amplitudes'].append(\
4895 DecayChainAmplitude(process_def,
4896 self.get('collect_mirror_procs'),
4897- self.get('ignore_six_quark_processes')))
4898+ self.get('ignore_six_quark_processes'),
4899+ diagram_filter=self['diagram_filter']))
4900 else:
4901 self['amplitudes'].extend(\
4902 self.generate_multi_amplitudes(process_def,
4903@@ -1666,7 +1669,8 @@
4904
4905 # Set automatic coupling orders
4906 process_definition.set('orders', MultiProcess.\
4907- find_optimal_process_orders(process_definition))
4908+ find_optimal_process_orders(process_definition,
4909+ diagram_filter))
4910 # Check for maximum orders from the model
4911 process_definition.check_expansion_orders()
4912
4913@@ -1848,7 +1852,7 @@
4914
4915
4916 @staticmethod
4917- def find_optimal_process_orders(process_definition):
4918+ def find_optimal_process_orders(process_definition, diagram_filter=False):
4919 """Find the minimal WEIGHTED order for this set of processes.
4920
4921 The algorithm:
4922@@ -2022,7 +2026,7 @@
4923
4924 amplitude = Amplitude({'process': process})
4925 try:
4926- amplitude.generate_diagrams()
4927+ amplitude.generate_diagrams(diagram_filter=diagram_filter)
4928 except InvalidCmd:
4929 failed_procs.append(tuple(sorted_legs))
4930 else:
4931
4932=== modified file 'madgraph/core/helas_objects.py'
4933--- madgraph/core/helas_objects.py 2016-03-22 20:44:25 +0000
4934+++ madgraph/core/helas_objects.py 2017-03-08 10:27:27 +0000
4935@@ -1379,6 +1379,18 @@
4936 # wavefunction number
4937 return new_wf, wf_number
4938
4939+ def has_multifermion(self):
4940+ """check the presence of 4 fermion vertex"""
4941+
4942+ mothers = self.get('mothers')
4943+ if len(mothers) >2:
4944+ nb_fermion = len([1 for wf in mothers if wf.is_fermion()])
4945+ if nb_fermion>2:
4946+ return True
4947+
4948+ return any(wf.has_multifermion() for wf in self.get('mothers'))
4949+
4950+
4951 def get_fermion_order(self):
4952 """Recursive function to get a list of fermion numbers
4953 corresponding to the order of fermions along fermion lines
4954@@ -1399,7 +1411,6 @@
4955
4956 other_fermions = [wf for wf in self.get('mothers') if \
4957 wf.is_fermion() and wf != fermion_mother]
4958-
4959 # Pick out bosons
4960 bosons = filter(lambda wf: wf.is_boson(), self.get('mothers'))
4961
4962@@ -1426,7 +1437,7 @@
4963
4964 if self.is_fermion():
4965 return [mother_list[0], fermion_number_list]
4966-
4967+
4968 return fermion_number_list
4969
4970 def needs_hermitian_conjugate(self):
4971@@ -2618,7 +2629,43 @@
4972 mystr = mystr + '\n}'
4973
4974 return mystr
4975-
4976+
4977+ def has_multifermion(self):
4978+
4979+ return any(wf.has_multifermion() for wf in self.get('mothers'))
4980+
4981+
4982+ def nice_string(self):
4983+ """ simple way to check which FD is related to this amplitude"""
4984+ def get_structure(wf):
4985+ """ funtion to allow to loop over helaswavefunction"""
4986+ mothers = []
4987+ try:
4988+ mothers = wf.get('mothers')
4989+ except:
4990+ if wf['is_loop']:
4991+ return '%s*' % wf['particle'].get('pdg_code')
4992+ else:
4993+ return wf['particle'].get('pdg_code')
4994+
4995+ struct = [get_structure(w) for w in mothers]
4996+ if struct:
4997+ if 'is_loop' in wf:
4998+ if wf['is_loop']:
4999+ return (struct,'>%s*'%wf.get('pdg_code') )
5000+ else:
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: