1
################################################################################
3
# Copyright (c) 2012 The MadGraph Development team and Contributors
5
# This file is a part of the MadGraph 5 project, an application which
6
# automatically generates Feynman diagrams and matrix elements for arbitrary
7
# high-energy processes in the Standard Model and beyond.
9
# It is subject to the MadGraph license which should accompany this
12
# For more information, please visit: http://madgraph.phys.ucl.ac.be
14
################################################################################
15
"""Program to combine results from channels that have been
16
split into multiple jobs. Multi-job channels are identified
17
by local file mjobs.dat in the channel directory.
19
from __future__ import division
26
import madgraph.various.sum_html as sum_html
28
import internal.sum_html as sum_html
30
logger = logging.getLogger('madevent.combine_run') # -> stdout
36
def get_inc_file(path):
37
"""read the information of fortran inc files and returns
38
the definition in a dictionary format.
39
This catch PARAMETER (NAME = VALUE)"""
41
pat = re.compile(r'''PARAMETER\s*\((?P<name>[_\w]*)\s*=\s*(?P<value>[\+\-\ded]*)\)''',
45
for name, value in pat.findall(open(path).read()):
46
orig_value = str(value)
48
out[name.lower()] = float(value.replace('d','e'))
50
out[name] = orig_value
53
class CombineRuns(object):
55
def __init__(self, me_dir, subproc=None):
60
subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
62
self.subproc = subproc
63
maxpart = get_inc_file(pjoin(me_dir, 'Source', 'maxparticles.inc'))
64
self.maxparticles = maxpart['max_particles']
67
for procname in self.subproc:
68
path = pjoin(self.me_dir,'SubProcesses', procname)
69
channels = self.get_channels(path)
70
for channel in channels:
71
self.sum_multichannel(channel)
73
def sum_multichannel(self, channel):
74
"""Looks in channel to see if there are multiple runs that
75
need to be combined. If so combines them into single run"""
77
alphabet = "abcdefghijklmnopqrstuvwxyz"
79
if os.path.exists(pjoin(channel, 'multijob.dat')):
80
njobs = int(open(pjoin(channel, 'multijob.dat')).read())
83
results = sum_html.Combine_results(channel)
85
logger.debug('find %s multijob in %s' % (njobs, channel))
88
for i in range(njobs):
89
if channel.endswith(os.path.pathsep):
90
path = channel[:-1] + alphabet[i]
92
path = channel + alphabet[i]
93
results.add_results(name=alphabet[i],
94
filepath=pjoin(path, 'results.dat'))
96
results.compute_average()
98
results.write_results_dat(pjoin(channel, 'results.dat'))
101
### Adding information in the log file
102
fsock = open(pjoin(channel, 'log.txt'), 'a')
103
fsock.write('--------------------- Multi run with %s jobs. ---------------------\n'
106
fsock.write('job %s : %s %s %s\n' % (r.name, r.xsec, r.axsec, r.nunwgt))
108
#Now read in all of the events and write them
109
#back out with the appropriate scaled weight
110
fsock = open(pjoin(channel, 'events.lhe'), 'w')
111
wgt = results.xsec / results.nunwgt
113
for result in results:
115
if channel.endswith(os.path.pathsep):
116
path = channel[:-1] + i
119
nw = self.copy_events(fsock, pjoin(path,'events.lhe'), wgt)
121
#logger.debug("Combined %s events to %s " % (tot_events, channel))
124
def copy_events(self, fsock, input, new_wgt):
125
""" Copy events from separate runs into one file w/ appropriate wgts"""
127
def get_fortran_str(nb):
129
nb, power = data.split('E')
131
power = int(power) + 1
132
return '%.7fE%+03i' %(nb,power)
133
new_wgt = get_fortran_str(new_wgt)
134
for line in open(input):
137
if float(data[2]) > 0:
141
line= ' %s %s%s %s\n' % (' '.join(data[:2]), sign,
142
new_wgt, ' '.join(data[3:]))
150
def get_channels(self, proc_path):
151
"""Opens file symfact.dat to determine all channels"""
152
sympath = os.path.join(proc_path, 'symfact.dat')
154
#ncode is number of digits needed for the bw coding
156
ncode = int(math.log10(3)*(self.maxparticles-3))+1
158
for line in open(sympath):
163
xi, j = float(xi), int(j)
167
npos = int(math.log10(k))+1
168
#Write with correct number of digits
172
dirname = 'G%.{0}f'.format(ncode) % xi
173
channels.append(os.path.join(proc_path,dirname))