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