1
2
3
4
5
6
7
8
9
10
11
12
13
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.
18 """
19 from __future__ import division
20 from __future__ import absolute_import
21 import math
22 import os
23 import re
24 import logging
25 from six.moves import range
26
27 try:
28 import madgraph
29 except ImportError:
30 import internal.sum_html as sum_html
31 import internal.misc as misc
32 from internal import InvalidCmd, MadGraph5Error
33 else:
34 import madgraph.madevent.sum_html as sum_html
35 import madgraph.various.misc as misc
36 from madgraph import InvalidCmd, MadGraph5Error, MG5DIR
37
38
39 logger = logging.getLogger('madevent.combine_run')
40
41
42 pjoin = os.path.join
46 """read the information of fortran inc files and returns
47 the definition in a dictionary format.
48 This catch PARAMETER (NAME = VALUE)"""
49
50 pat = re.compile(r'''PARAMETER\s*\((?P<name>[_\w]*)\s*=\s*(?P<value>[\+\-\ded]*)\)''',
51 re.I)
52
53 out = {}
54 for name, value in pat.findall(open(path).read()):
55 orig_value = str(value)
56 try:
57 out[name.lower()] = float(value.replace('d','e'))
58 except ValueError:
59 out[name] = orig_value
60 return out
61
63
64 - def __init__(self, me_dir, subproc=None):
65
66 self.me_dir = me_dir
67
68 if not subproc:
69 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
70 'subproc.mg'))]
71 self.subproc = subproc
72 maxpart = get_inc_file(pjoin(me_dir, 'Source', 'maxparticles.inc'))
73 self.maxparticles = maxpart['max_particles']
74
75
76 for procname in self.subproc:
77 path = pjoin(self.me_dir,'SubProcesses', procname)
78 channels = self.get_channels(path)
79 for channel in channels:
80 self.sum_multichannel(channel)
81
83 """Looks in channel to see if there are multiple runs that
84 need to be combined. If so combines them into single run"""
85
86 alphabet = "abcdefghijklmnopqrstuvwxyz"
87
88 if os.path.exists(pjoin(channel, 'multijob.dat')):
89 njobs = int(open(pjoin(channel, 'multijob.dat')).read())
90 else:
91 return
92 results = sum_html.Combine_results(channel)
93 if njobs:
94 logger.debug('find %s multijob in %s' % (njobs, channel))
95 else:
96 return
97 for i in range(njobs):
98 if channel.endswith(os.path.pathsep):
99 path = channel[:-1] + alphabet[i % 26] + str((i+1)//26)
100 else:
101 path = channel + alphabet[i % 26] + str((i+1)//26)
102 results.add_results(name=alphabet[i % 26] + str((i+1)//26) ,
103 filepath=pjoin(path, 'results.dat'))
104
105 results.compute_average()
106 if results.xsec:
107 results.write_results_dat(pjoin(channel, 'results.dat'))
108 else:
109 return
110
111 fsock = open(pjoin(channel, 'log.txt'), 'a')
112 fsock.write('--------------------- Multi run with %s jobs. ---------------------\n'
113 % njobs)
114 for r in results:
115 fsock.write('job %s : %s %s +- %s %s\n' % (r.name, r.xsec, r.axsec,\
116 r.xerru, r.nunwgt))
117
118
119
120 fsock = open(pjoin(channel, 'events.lhe'), 'w')
121 wgt = results.axsec / results.nunwgt
122 tot_nevents, nb_file = 0, 0
123 for result in results:
124 i = result.name
125 if channel.endswith(os.path.pathsep):
126 path = channel[:-1] + i
127 else:
128 path = channel + i
129 nw = self.copy_events(fsock, pjoin(path,'events.lhe'), wgt)
130 tot_nevents += nw
131 nb_file += 1
132 logger.debug("Combined %s file generating %s events for %s " , nb_file, tot_nevents, channel)
133
134 @staticmethod
136 data = '%E' % nb
137 nb, power = data.split('E')
138 nb = abs(float(nb)) /10
139 power = int(power) + 1
140 return '%.7fE%+03i' %(nb,power)
141
142
144 """ Copy events from separate runs into one file w/ appropriate wgts"""
145
146
147 new_wgt = self.get_fortran_str(new_wgt)
148 old_line = ""
149 nb_evt =0
150 for line in open(input):
151 if old_line.startswith("<event>"):
152 nb_evt+=1
153 data = line.split()
154 if not len(data) == 6:
155 raise MadGraph5Error("Line after <event> should have 6 entries")
156 if float(data[2]) > 0:
157 sign = ''
158 else:
159 sign = '-'
160 line= ' %s %s%s %s\n' % (' '.join(data[:2]), sign,
161 new_wgt, ' '.join(data[3:]))
162 fsock.write(line)
163 old_line = line
164 return nb_evt
166 """Opens file symfact.dat to determine all channels"""
167 sympath = os.path.join(proc_path, 'symfact.dat')
168
169
170
171 ncode = int(math.log10(3)*(self.maxparticles-3))+1
172 channels = []
173 for line in open(sympath):
174 try:
175 xi, j = line.split()
176 except Exception:
177 break
178 xi, j = float(xi), int(j)
179
180 if j > 0:
181 k = int(xi)
182 npos = int(math.log10(k))+1
183
184 if xi == k:
185 dirname = 'G%i' % k
186 else:
187 dirname = 'G%.{0}f'.format(ncode) % xi
188 channels.append(os.path.join(proc_path,dirname))
189 return channels
190