Merge lp:~maddevelopers/mg5amcnlo/reduce_aloha_call into lp:~maddevelopers/mg5amcnlo/version_1_0_1
- reduce_aloha_call
- Merge into version_1_0_1
Status: | Merged |
---|---|
Merged at revision: | 135 |
Proposed branch: | lp:~maddevelopers/mg5amcnlo/reduce_aloha_call |
Merge into: | lp:~maddevelopers/mg5amcnlo/version_1_0_1 |
Diff against target: |
3370 lines (+1463/-564) (has conflicts) 21 files modified
aloha/aloha_writers.py (+465/-106) aloha/bin/aloha (+1/-1) aloha/create_aloha.py (+94/-17) madgraph/core/helas_objects.py (+122/-77) madgraph/interface/cmd_interface.py (+0/-1) madgraph/iolibs/export_cpp.py (+39/-29) madgraph/iolibs/export_python.py (+5/-3) madgraph/iolibs/export_v4.py (+0/-9) madgraph/iolibs/helas_call_writers.py (+142/-129) madgraph/iolibs/template_files/matrix_madevent_v4.inc (+2/-0) madgraph/iolibs/template_files/matrix_standalone_v4.inc (+2/-0) tests/acceptance_tests/test_cmd.py (+6/-6) tests/parallel_tests/me_comparator.py (+3/-2) tests/parallel_tests/sample_script.py (+18/-1) tests/unit_tests/core/test_helas_objects.py (+8/-6) tests/unit_tests/iolibs/test_export_cpp.py (+132/-10) tests/unit_tests/iolibs/test_export_python.py (+15/-24) tests/unit_tests/iolibs/test_export_v4.py (+77/-117) tests/unit_tests/iolibs/test_helas_call_writers.py (+2/-2) tests/unit_tests/various/test_4fermion_models.py (+0/-1) tests/unit_tests/various/test_aloha.py (+330/-23) Text conflict in tests/parallel_tests/sample_script.py Text conflict in tests/unit_tests/iolibs/test_export_cpp.py Text conflict in tests/unit_tests/iolibs/test_export_v4.py |
To merge this branch: | bzr merge lp:~maddevelopers/mg5amcnlo/reduce_aloha_call |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Johan Alwall (community) | Approve | ||
Review via email: mp+58534@code.launchpad.net |
Commit message
Description of the change
- Merge multiple aloha call in a single one. (for same order/color)
- Add open command in cmd_interface
- Enlarge the symmetry possibility for aloha.
- small debug/improvment
Please check carefully the CPP output. (read at least one formated output)
Olivier Mattelaer (olivier-mattelaer) wrote : | # |
>Hello Olivier,
>
>This is really cool! I do have a couple of questions about the code:
>1) Did you add the check in the ALOHA routines if COUP == 0 (in that case exit with zero wf/amp)?
> This check should not be in the combined routines of course, only in the basic routines.
Indeed, this is not done yet.
In fact, I'm still quite puzzled about this point.
A much better way would be to have a python script which evaluates the couplings
and simplify the matrix.f when a COUP is equal to zero(by commenting line and defining amp to zero) --off course in a reversal way--
They are many advantages to do like this:
1) you can bypass the computation of the full amplitude. (and not only on the interactions with zero couplings
2) This is done once and for all. (compare to a point by point if statement)
The disadvantages are
1) request python on the node. (We are moving for more python so this should be fine)
2) request a new compilation for each param_card (since matrix.f is modified)
3) This is much more work...
I think the advantages (speed) are enough relevant in order to pass to this method.
I would just propose to have a tag in matrix.f in order to forbid such simplification.
This will help for some test.
Note that with such method, I would need a check for the coupling be equal to zero but only in the combined routine... so exactly the opposite
>2) In aloha_writers, you do
> # Define which part of the routine should be called
> if 'C' in self.namestring:
> addon = 'C' +self.namestrin
> else:
> addon = '_%s' % self.offshell
> What if a used calls the Lorentz something with a 'C' in the name?
> (this might apply in other places too)
>Update: " alohafile_pattern = re.compile(
> So in fact you are not allowing the user freedom to select lorentz names outside of the
> FR defined ones? This of course solves the problem.
Indeed not FR pattern are allowed, and indeed, name with "C" might creates trouble.
I will think about that problem, but I don't think I can find a way working in 100% of the case.
(But I can reduce the problem to routines ending by C\d)
>3) + # Two possible scheme FFV1C1_2_X or FFV1__FFV2C1_X
> Why use double "_" for the combined name instead of the slightly better FFV1_FFV2C1_X?
Ok I can change it.
Olivier Mattelaer (olivier-mattelaer) wrote : | # |
Hi valentin,all,
I propose that we discuss this not on launchpad and on the ticket but
rather directly by email.
I've already send my comment on this point.
Cheers,
Olivier
On 21-avr.-11, at 11:27, Valentin Hirschi wrote:
>
>
> On Thu, Apr 21, 2011 at 11:20 AM, Valentin Hirschi <<email address hidden>
> > wrote:
>
> On Thu, Apr 21, 2011 at 10:50 AM, Olivier Mattelaer <<email address hidden>
> > wrote:
> >Hello Olivier,
> >
> >This is really cool! I do have a couple of questions about the code:
> >1) Did you add the check in the ALOHA routines if COUP == 0 (in
> that case exit with zero wf/amp)?
> > This check should not be in the combined routines of course,
> only in the basic routines.
>
> Indeed, this is not done yet.
> In fact, I'm still quite puzzled about this point.
> A much better way would be to have a python script which evaluates
> the couplings
> and simplify the matrix.f when a COUP is equal to zero(by commenting
> line and defining amp to zero) --off course in a reversal way--
>
> They are many advantages to do like this:
> 1) you can bypass the computation of the full amplitude. (and not
> only on the interactions with zero couplings
> 2) This is done once and for all. (compare to a point by point if
> statement)
>
> Wait... I did not read this correctly the first time! Do you
> actually consider some if statement (with a condition being directly
> a true/false variable) an actual computing time cost to consider???
> (for the amplitude it's the same, you can have one general if
> statement englobing the whole thing).
> I'm no expert, but I believe that this cannot possibly slow the
> code! I hardly see this if statement taking more than 1/1000
> thousand of the time used to compute a HELAS amplitude call (which
> would be the only one here at the very least).
> For NLO this is for sure totally irrelevant, and I think it's still
> negligible for LO, but if this is indeed something to consider, then
> all what I said is void and this script is indeed the way to go.
>
> The disadvantages are
> 1) request python on the node. (We are moving for more python so
> this should be fine)
> 2) request a new compilation for each param_card (since matrix.f is
> modified)
> 3) This is much more work...
>
> I think the advantages (speed) are enough relevant in order to pass
> to this method.
> I would just propose to have a tag in matrix.f in order to forbid
> such simplification.
> This will help for some test.
>
> Note that with such method, I would need a check for the coupling be
> equal to zero but only in the combined routine... so exactly the
> opposite
>
> Hi all!
>
> I'm of course not very into what you guys are doing, so all what
> follows might be completely out of context and irrelevant, so sorry
> in advance for that.
>
> I just wanted to understand why you really insist on having matrix.f
> with hardcoded elimination of amplitudes being zero because of the
> coupling constants?
> Wouldn't be nice to have a subroutine in matrix.f like the one I
> have in MadLoop which is something like InitMatrixEleme
>
> This subroutine reads the parameters intended ...
Johan Alwall (johan-alwall) wrote : | # |
Hello Olivier,
Awesome job!
Some comments on the new version:
1) when I write open <TAB> (without any generation) it only gives me
MG5_debug, so gives no hint that ./ is possible. I would prefer
MG5_debug and ./ as completions. Fixed.
2) mg5>open ./PROC_
"Unable to find application named 'None'" - I fixed this too .
For the open and launch commands:
3) We should definitely not have the same code twice, so I put all the
open code in launch. Feel free to change this.
4) On Mac, you can't use the "open" command for text files, since
there's no way to make it wait for the return. So I only allow inline
editors (emacs is always defined). So I changed this.
3) In the code:
+ short_name, addon = name.split('C',1)
+ try:
+ addon = 'C' + str(int(addon))
+ except:
+ addon = ''
+ else:
+ name = short_name
I don't understand how this solves or improves the issue.
All we need is to ensure that the user doesn't use non-FR characters,
which is what they would assume anyway. Also not nice that this comes
multiple times - it's sufficiently complicated to warrant its own
routine (which also allows to modify it easily). But I would prefer to
go back to the previous case.
But I guess it doesn't matter at this point - just to keep in mind for
the future.
Cheers,
Johan
Johan Alwall (johan-alwall) wrote : | # |
Hello Olivier,
Please don't do any more edits in this branch, but work directly in the version_1_0_1 branch from now on.
Cheers,
Johan
Preview Diff
1 | === modified file 'aloha/aloha_writers.py' |
2 | --- aloha/aloha_writers.py 2011-04-01 22:38:18 +0000 |
3 | +++ aloha/aloha_writers.py 2011-04-20 16:57:29 +0000 |
4 | @@ -19,10 +19,16 @@ |
5 | |
6 | def __init__(self, abstract_routine, dirpath): |
7 | |
8 | + |
9 | + name = get_routine_name(abstract_routine.name, abstract_routine.outgoing) |
10 | + if dirpath: |
11 | + self.dir_out = dirpath |
12 | + self.out_path = os.path.join(dirpath, name + self.extension) |
13 | + else: |
14 | + self.out_path = None |
15 | + self.dir_out = None |
16 | + |
17 | self.obj = abstract_routine.expr |
18 | - name = get_routine_name(abstract_routine.name, abstract_routine.outgoing) |
19 | - self.out_path = os.path.join(dirpath, name + self.extension) |
20 | - self.dir_out = dirpath |
21 | self.particles = [self.type_to_variable[spin] for spin in \ |
22 | abstract_routine.spins] |
23 | self.namestring = name |
24 | @@ -36,6 +42,9 @@ |
25 | self.make_all_lists() # Compute the expression for the call ordering |
26 | #the definition of objects,.. |
27 | |
28 | + |
29 | + |
30 | + |
31 | def pass_to_HELAS(self, indices, start=0): |
32 | """find the Fortran HELAS position for the list of index""" |
33 | |
34 | @@ -170,18 +179,19 @@ |
35 | |
36 | return call_arg |
37 | |
38 | - def reorder_call_list(self, call_list, old, new): |
39 | - """ restore the correct order for symmetries """ |
40 | - spins = self.particles |
41 | - assert(0 < old < new) |
42 | - old, new = old -1, new -1 # pass in real position in particles list |
43 | - assert(spins[old] == spins[new]) |
44 | - spin =spins[old] |
45 | - |
46 | - new_call = call_list[:] |
47 | - val = new_call.pop(old) |
48 | - new_call.insert(new - 1, val) |
49 | - return new_call |
50 | +# def reorder_call_list(self, call_list, old, new): |
51 | +# """ restore the correct order for symmetries """ |
52 | +# raise |
53 | +# #spins = self.particles |
54 | +# #assert(0 < old < new) |
55 | +# #old, new = old -1, new -1 # pass in real position in particles list |
56 | +# #assert(spins[old] == spins[new]) |
57 | +# #spin =spins[old] |
58 | +# |
59 | +# new_call = call_list[:] |
60 | +# #val = new_call.pop(old) |
61 | +# #new_call.insert(new - 1, val) |
62 | +# return new_call |
63 | |
64 | |
65 | def make_momentum_conservation(self): |
66 | @@ -249,42 +259,45 @@ |
67 | 'V':'double complex V%d(6)', |
68 | 'T':'double complex T%s(18)'} |
69 | |
70 | - def define_header(self): |
71 | + def define_header(self, name=None): |
72 | """Define the Header of the fortran file. This include |
73 | - function tag |
74 | - definition of variable |
75 | """ |
76 | - |
77 | + |
78 | + if not name: |
79 | + name = self.namestring |
80 | + |
81 | Momenta = self.collected['momenta'] |
82 | OverM = self.collected['om'] |
83 | |
84 | CallList = self.calllist['CallList'] |
85 | declare_list = self.calllist['DeclareList'] |
86 | - if 'double complex C' in declare_list: |
87 | + if 'double complex COUP' in declare_list: |
88 | alredy_update = True |
89 | else: |
90 | alredy_update = False |
91 | |
92 | if not alredy_update: |
93 | - declare_list.append('double complex C') |
94 | + declare_list.append('double complex COUP') |
95 | |
96 | # define the type of function and argument |
97 | if not self.offshell: |
98 | str_out = 'subroutine %(name)s(%(args)s,vertex)\n' % \ |
99 | - {'name': self.namestring, |
100 | - 'args': ','.join(CallList+ ['C']) } |
101 | + {'name': name, |
102 | + 'args': ','.join(CallList+ ['COUP']) } |
103 | if not alredy_update: |
104 | - declare_list.append('double complex vertex\n') |
105 | + declare_list.append('double complex vertex') |
106 | else: |
107 | if not alredy_update: |
108 | declare_list.append('double complex denom') |
109 | declare_list.append('double precision M%(id)d, W%(id)d' % |
110 | {'id': self.offshell}) |
111 | - call_arg = '%(args)s, C, M%(id)d, W%(id)d, %(spin)s%(id)d' % \ |
112 | + call_arg = '%(args)s, COUP, M%(id)d, W%(id)d, %(spin)s%(id)d' % \ |
113 | {'args': ', '.join(CallList), |
114 | 'spin': self.particles[self.offshell -1], |
115 | 'id': self.offshell} |
116 | - str_out = ' subroutine %s(%s)\n' % (self.namestring, call_arg) |
117 | + str_out = ' subroutine %s(%s)\n' % (name, call_arg) |
118 | |
119 | # Forcing implicit None |
120 | str_out += 'implicit none \n' |
121 | @@ -402,7 +415,7 @@ |
122 | OutString = '' |
123 | if not self.offshell: |
124 | for ind in self.obj.listindices(): |
125 | - string = 'Vertex = C*' + self.write_obj(self.obj.get_rep(ind)) |
126 | + string = 'Vertex = COUP*' + self.write_obj(self.obj.get_rep(ind)) |
127 | string = string.replace('+-', '-') |
128 | string = re.sub('\((?P<num>[+-]*[0-9])(?P<num2>[+-][0-9])[Jj]\)\.', '(\g<num>d0,\g<num2>d0)', string) |
129 | string = re.sub('(?P<num>[0-9])[Jj]\.', '\g<num>.*(0d0,1d0)', string) |
130 | @@ -420,7 +433,7 @@ |
131 | string = re.sub('(?P<num>[0-9])[Jj]\.', '\g<num>*(0d0,1d0)', string) |
132 | OutString = OutString + string + '\n' |
133 | for ind in numerator.listindices(): |
134 | - string = '%s(%d)= C*denom*' % (OffShellParticle, self.pass_to_HELAS(ind, start=1)) |
135 | + string = '%s(%d)= COUP*denom*' % (OffShellParticle, self.pass_to_HELAS(ind, start=1)) |
136 | string += self.write_obj(numerator.get_rep(ind)) |
137 | string = string.replace('+-', '-') |
138 | string = re.sub('\((?P<num>[+-][0-9])\+(?P<num2>[+-][0-9])[Jj]\)\.', '(\g<num>d0,\g<num2>d0)', string) |
139 | @@ -430,45 +443,167 @@ |
140 | |
141 | def define_symmetry(self, new_nb): |
142 | number = self.offshell |
143 | - calls = self.reorder_call_list(self.calllist['CallList'], self.offshell, |
144 | - new_nb) |
145 | - Outstring = 'call '+self.namestring+'('+','.join(calls)+',C,M%s,W%s,%s%s)' \ |
146 | + calls = self.calllist['CallList'] |
147 | + |
148 | + Outstring = 'call '+self.namestring+'('+','.join(calls)+',COUP,M%s,W%s,%s%s)\n' \ |
149 | %(number,number,self.particles[number-1],number) |
150 | return Outstring |
151 | |
152 | def define_foot(self): |
153 | - return 'end' |
154 | + return 'end\n\n' |
155 | |
156 | def write(self, mode='self'): |
157 | - |
158 | - writer = writers.FortranWriter(self.out_path) |
159 | - writer.downcase = False |
160 | - commentstring = 'This File is Automatically generated by ALOHA \n' |
161 | - commentstring += 'The process calculated in this file is: \n' |
162 | - commentstring += self.comment + '\n' |
163 | - writer.write_comments(commentstring) |
164 | - |
165 | + |
166 | # write head - momenta - body - foot |
167 | - writer.writelines(self.define_header()) |
168 | - writer.writelines(self.define_momenta()) |
169 | - writer.writelines(self.define_expression()) |
170 | - writer.writelines(self.define_foot()) |
171 | + text = self.define_header()+'\n' |
172 | + text += self.define_momenta()+'\n' |
173 | + text += self.define_expression() |
174 | + text += self.define_foot() |
175 | |
176 | + sym_text = [] |
177 | for elem in self.symmetries: |
178 | symmetryhead = self.define_header().replace( \ |
179 | self.namestring,self.namestring[0:-1]+'%s' %(elem)) |
180 | symmetrybody = self.define_symmetry(elem) |
181 | - writer.write_comments('\n%s\n' % ('#'*65)) |
182 | - writer.writelines(symmetryhead) |
183 | - writer.writelines(symmetrybody) |
184 | - writer.writelines(self.define_foot()) |
185 | - |
186 | - |
187 | + |
188 | + sym_text.append(symmetryhead + symmetrybody + self.define_foot()) |
189 | + |
190 | + |
191 | + if self.out_path: |
192 | + writer = writers.FortranWriter(self.out_path) |
193 | + writer.downcase = False |
194 | + commentstring = 'This File is Automatically generated by ALOHA \n' |
195 | + commentstring += 'The process calculated in this file is: \n' |
196 | + commentstring += self.comment + '\n' |
197 | + writer.write_comments(commentstring) |
198 | + writer.writelines(text) |
199 | + for text in sym_text: |
200 | + writer.write_comments('\n%s\n' % ('#'*65)) |
201 | + writer.writelines(text) |
202 | + else: |
203 | + for stext in sym_text: |
204 | + text += '\n\n' + stext |
205 | + |
206 | + return text + '\n' |
207 | + |
208 | + def write_combined(self, lor_names, mode='self', offshell=None): |
209 | + """Write routine for combine ALOHA call (more than one coupling)""" |
210 | + |
211 | + # Set some usefull command |
212 | + if offshell is None: |
213 | + sym = 1 |
214 | + offshell = self.offshell |
215 | + else: |
216 | + sym = None # deactivate symetry |
217 | + |
218 | + name = combine_name(self.abstractname, lor_names, offshell) |
219 | + |
220 | + |
221 | + # write header |
222 | + header = self.define_header(name=name) |
223 | + new_couplings = ['COUP%s' % (i+1) for i in range(len(lor_names)+1)] |
224 | + text = header.replace('COUP', ','.join(new_couplings)) |
225 | + # define the TMP for storing output |
226 | + if not offshell: |
227 | + text += ' double complex TMP\n' |
228 | + else: |
229 | + spin = self.particles[offshell -1] |
230 | + text += ' double complex TMP(%s)\n integer i' % self.type_to_size[spin] |
231 | + |
232 | + # Define which part of the routine should be called |
233 | + if 'C' in self.namestring: |
234 | + addon = 'C' +self.namestring.split('C',1)[1] |
235 | + else: |
236 | + addon = '_%s' % self.offshell |
237 | + |
238 | + # how to call the routine |
239 | + if not offshell: |
240 | + main = 'vertex' |
241 | + call_arg = '%(args)s, %(COUP)s, %(LAST)s' % \ |
242 | + {'args': ', '.join(self.calllist['CallList']), |
243 | + 'COUP':'COUP%d', |
244 | + 'spin': self.particles[self.offshell -1], |
245 | + 'LAST': '%s'} |
246 | + else: |
247 | + main = '%(spin)s%(id)d' % \ |
248 | + {'spin': self.particles[offshell -1], |
249 | + 'id': self.offshell} |
250 | + call_arg = '%(args)s, %(COUP)s, M%(id)d, W%(id)d, %(LAST)s' % \ |
251 | + {'args': ', '.join(self.calllist['CallList']), |
252 | + 'COUP':'COUP%d', |
253 | + 'id': self.offshell, |
254 | + 'LAST': '%s'} |
255 | + |
256 | + # make the first call |
257 | + line = " CALL %s%s("+call_arg+")\n" |
258 | + text += '\n\n' + line % (self.namestring, '', 1, main) |
259 | + |
260 | + # make the other call |
261 | + for i,lor in enumerate(lor_names): |
262 | + text += line % (lor, addon, i+2, 'TMP') |
263 | + if not offshell: |
264 | + text += ' vertex = vertex + tmp\n' |
265 | + else: |
266 | + size = self.type_to_size[spin] -2 |
267 | + text += """ do i=1,%(id)d |
268 | + %(main)s(i) = %(main)s(i) + tmp(i) |
269 | + enddo\n""" % {'id': size, 'main':main} |
270 | + |
271 | + |
272 | + text += self.define_foot() |
273 | + |
274 | + #ADD SYMETRY |
275 | + if sym: |
276 | + for elem in self.symmetries: |
277 | + text += self.write_combined(lor_names, mode, elem) |
278 | + |
279 | + |
280 | + if self.out_path: |
281 | + # Prepare a specific file |
282 | + path = os.path.join(os.path.dirname(self.out_path), name+'.f') |
283 | + writer = writers.FortranWriter(path) |
284 | + writer.downcase = False |
285 | + commentstring = 'This File is Automatically generated by ALOHA \n' |
286 | + writer.write_comments(commentstring) |
287 | + writer.writelines(text) |
288 | + |
289 | + return text |
290 | + |
291 | def get_routine_name(name,outgoing): |
292 | """ build the name of the aloha function """ |
293 | |
294 | return '%s_%s' % (name, outgoing) |
295 | |
296 | +def combine_name(name, other_names, outgoing): |
297 | + """ build the name for combined aloha function """ |
298 | + |
299 | + # Two possible scheme FFV1C1_2_X or FFV1__FFV2C1_X |
300 | + # If they are all in FFVX scheme then use the first |
301 | + p=re.compile('^(?P<type>[FSVT]+)(?P<id>\d+)') |
302 | + routine = '' |
303 | + if p.search(name): |
304 | + base, id = p.search(name).groups() |
305 | + routine = name |
306 | + for s in other_names: |
307 | + try: |
308 | + base2,id2 = p.search(s).groups() |
309 | + except: |
310 | + routine = '' |
311 | + break # one matching not good -> other scheme |
312 | + if base != base2: |
313 | + routine = '' |
314 | + break # one matching not good -> other scheme |
315 | + else: |
316 | + routine += '_%s' % id2 |
317 | + if routine: |
318 | + return routine +'_%s' % outgoing |
319 | + |
320 | + addon = '' |
321 | + if 'C' in name: |
322 | + name, addon = name.split('C',1) |
323 | + addon = 'C' + addon |
324 | + return '__'.join((name,) + tuple(other_names)) + addon + '_%s' % outgoing |
325 | + |
326 | class ALOHAWriterForCPP(WriteALOHA): |
327 | """Routines for writing out helicity amplitudes as C++ .h and .cc files.""" |
328 | |
329 | @@ -477,17 +612,20 @@ |
330 | 'V':'double complex V%d[6]', |
331 | 'T':'double complex T%s[18]'} |
332 | |
333 | - def define_header(self): |
334 | + def define_header(self, name=None): |
335 | """Define the headers for the C++ .h and .cc files. This include |
336 | - function tag |
337 | - definition of variable |
338 | - momentum conservation |
339 | """ |
340 | + |
341 | + if name is None: |
342 | + name = self.namestring |
343 | |
344 | #Width = self.collected['width'] |
345 | #Mass = self.collected['mass'] |
346 | |
347 | - CallList = self.calllist['CallList'] |
348 | + CallList = self.calllist['CallList'][:] |
349 | |
350 | local_declare = [] |
351 | OffShell = self.offshell |
352 | @@ -503,12 +641,12 @@ |
353 | # define the type of function and argument |
354 | if not OffShell: |
355 | str_out = 'void %(name)s(%(args)s, complex<double>& vertex)' % \ |
356 | - {'name': self.namestring, |
357 | - 'args': ','.join(CallList + ['complex<double> C'])} |
358 | + {'name': name, |
359 | + 'args': ','.join(CallList + ['complex<double> COUP'])} |
360 | else: |
361 | str_out = 'void %(name)s(%(args)s, double M%(number)d, double W%(number)d, complex<double>%(out)s%(number)d[])' % \ |
362 | - {'name': self.namestring, |
363 | - 'args': ','.join(CallList+ ['complex<double> C']), |
364 | + {'name': name, |
365 | + 'args': ','.join(CallList+ ['complex<double> COUP']), |
366 | 'out': self.particles[OffShellParticle], |
367 | 'number': OffShellParticle + 1 |
368 | } |
369 | @@ -613,7 +751,7 @@ |
370 | OutString = '' |
371 | if not self.offshell: |
372 | for ind in self.obj.listindices(): |
373 | - string = 'vertex = C*' + self.write_obj(self.obj.get_rep(ind)) |
374 | + string = 'vertex = COUP*' + self.write_obj(self.obj.get_rep(ind)) |
375 | string = string.replace('+-', '-') |
376 | OutString = OutString + string + ';\n' |
377 | else: |
378 | @@ -626,7 +764,7 @@ |
379 | string = string.replace('+-', '-') |
380 | OutString = OutString + string + ';\n' |
381 | for ind in numerator.listindices(): |
382 | - string = '%s[%d]= C*denom*' % (OffShellParticle, self.pass_to_HELAS(ind)) |
383 | + string = '%s[%d]= COUP*denom*' % (OffShellParticle, self.pass_to_HELAS(ind)) |
384 | string += self.write_obj(numerator.get_rep(ind)) |
385 | string = string.replace('+-', '-') |
386 | OutString = OutString + string + ';\n' |
387 | @@ -636,8 +774,7 @@ |
388 | remove_double = re.compile('complex<double> (?P<name>[\w]+)\[\]') |
389 | def define_symmetry(self, new_nb): |
390 | """Write the call for symmetric routines""" |
391 | - calls = self.reorder_call_list(self.calllist['CallList'], |
392 | - self.offshell, new_nb) |
393 | + calls = self.calllist['CallList'] |
394 | |
395 | for i, call in enumerate(calls): |
396 | if self.remove_double.match(call): |
397 | @@ -647,22 +784,24 @@ |
398 | #calls = [self.remove_double.match(call).group('name') for call in \ |
399 | # calls] |
400 | number = self.offshell |
401 | - Outstring = self.namestring+'('+','.join(calls)+',C,M%s,W%s,%s%s);' \ |
402 | + Outstring = self.namestring+'('+','.join(calls)+',COUP,M%s,W%s,%s%s);\n' \ |
403 | %(number,number,self.particles[self.offshell-1],number) |
404 | return Outstring |
405 | |
406 | def define_foot(self): |
407 | """Return the end of the function definition""" |
408 | |
409 | - return '}\n' |
410 | + return '}\n\n' |
411 | |
412 | - def write_h(self, header): |
413 | + def write_h(self, header, compiler_cmd=True): |
414 | """Return the full contents of the .h file""" |
415 | |
416 | - h_string = '#ifndef '+ self.namestring + '_guard\n' |
417 | - h_string += '#define ' + self.namestring + '_guard\n' |
418 | - h_string += '#include <complex>\n' |
419 | - h_string += 'using namespace std;\n\n' |
420 | + h_string = '' |
421 | + if compiler_cmd: |
422 | + h_string = '#ifndef '+ self.namestring + '_guard\n' |
423 | + h_string += '#define ' + self.namestring + '_guard\n' |
424 | + h_string += '#include <complex>\n' |
425 | + h_string += 'using namespace std;\n\n' |
426 | |
427 | h_header = header['h_header'] |
428 | |
429 | @@ -672,15 +811,44 @@ |
430 | symmetryhead = h_header.replace( \ |
431 | self.namestring,self.namestring[0:-1]+'%s' %(elem)) |
432 | h_string += symmetryhead |
433 | - |
434 | - h_string += '#endif' |
435 | + |
436 | + if compiler_cmd: |
437 | + h_string += '#endif\n\n' |
438 | |
439 | return h_string |
440 | |
441 | - def write_cc(self, header): |
442 | + def write_combined_h(self, lor_names, offshell=None, compiler_cmd=True): |
443 | + """Return the content of the .h file linked to multiple lorentz call.""" |
444 | + |
445 | + name = combine_name(self.abstractname, lor_names, offshell) |
446 | + text= '' |
447 | + if compiler_cmd: |
448 | + text = '#ifndef '+ name + '_guard\n' |
449 | + text += '#define ' + name + '_guard\n' |
450 | + text += '#include <complex>\n' |
451 | + text += 'using namespace std;\n\n' |
452 | + |
453 | + # write header |
454 | + header = self.define_header(name=name) |
455 | + h_header = header['h_header'] |
456 | + new_couplings = ['COUP%s' % (i+1) for i in range(len(lor_names)+1)] |
457 | + h_string = h_header.replace('COUP', ', complex <double>'.join(new_couplings)) |
458 | + text += h_string |
459 | + |
460 | + for elem in self.symmetries: |
461 | + text += h_string.replace(name, name[0:-1]+str(elem)) |
462 | + |
463 | + if compiler_cmd: |
464 | + text += '#endif' |
465 | + |
466 | + return text |
467 | + |
468 | + def write_cc(self, header, compiler_cmd=True): |
469 | """Return the full contents of the .cc file""" |
470 | |
471 | - cc_string = '#include \"%s.h\"\n\n' % self.namestring |
472 | + cc_string = '' |
473 | + if compiler_cmd: |
474 | + cc_string = '#include \"%s.h\"\n\n' % self.namestring |
475 | cc_header = header['cc_header'] |
476 | cc_string += cc_header |
477 | cc_string += self.define_momenta() |
478 | @@ -696,24 +864,149 @@ |
479 | cc_string += self.define_foot() |
480 | |
481 | return cc_string |
482 | + |
483 | + def write_combined_cc(self, lor_names, offshell=None, compiler_cmd=True, sym=True): |
484 | + "Return the content of the .cc file linked to multiple lorentz call." |
485 | + |
486 | + # Set some usefull command |
487 | + if offshell is None: |
488 | + offshell = self.offshell |
489 | + |
490 | + name = combine_name(self.abstractname, lor_names, offshell) |
491 | + |
492 | + text = '' |
493 | + if compiler_cmd: |
494 | + text += '#include "%s.h"\n\n' % name |
495 | + |
496 | + # write header |
497 | + header = self.define_header(name=name)['cc_header'] |
498 | + new_couplings = ['COUP%s' % (i+1) for i in range(len(lor_names)+1)] |
499 | + text += header.replace('COUP', ', complex<double>'.join(new_couplings)) |
500 | + # define the TMP for storing output |
501 | + if not offshell: |
502 | + text += 'complex<double> tmp;\n' |
503 | + else: |
504 | + spin = self.particles[offshell -1] |
505 | + text += 'complex<double> tmp[%s];\n int i = 0;' % self.type_to_size[spin] |
506 | + |
507 | + # Define which part of the routine should be called |
508 | + if 'C' in self.namestring: |
509 | + addon = 'C' +self.namestring.split('C',1)[1] |
510 | + else: |
511 | + addon = '_%s' % self.offshell |
512 | + |
513 | + # how to call the routine |
514 | + if not offshell: |
515 | + main = 'vertex' |
516 | + call_arg = '%(args)s, %(COUP)s, %(LAST)s' % \ |
517 | + {'args': ', '.join(self.calllist['CallList']), |
518 | + 'COUP':'COUP%d', |
519 | + 'spin': self.particles[self.offshell -1], |
520 | + 'LAST': '%s'} |
521 | + else: |
522 | + main = '%(spin)s%(id)d' % \ |
523 | + {'spin': self.particles[self.offshell -1], |
524 | + 'id': self.offshell} |
525 | + call_arg = '%(args)s, %(COUP)s, M%(id)d, W%(id)d, %(LAST)s' % \ |
526 | + {'args': ', '.join(self.calllist['CallList']), |
527 | + 'COUP':'COUP%d', |
528 | + 'id': self.offshell, |
529 | + 'LAST': '%s'} |
530 | + |
531 | + # make the first call |
532 | + line = "%s%s("+call_arg+");\n" |
533 | + text += '\n\n' + line % (self.namestring, '', 1, main) |
534 | + |
535 | + # make the other call |
536 | + for i,lor in enumerate(lor_names): |
537 | + text += line % (lor, addon, i+2, 'tmp') |
538 | + if not offshell: |
539 | + text += ' vertex = vertex + tmp;\n' |
540 | + else: |
541 | + size = self.type_to_size[spin] -2 |
542 | + text += """ while (i < %(id)d) |
543 | + { |
544 | + %(main)s[i] = %(main)s[i] + tmp[i]; |
545 | + i++; |
546 | + }\n""" % {'id': size, 'main':main} |
547 | + |
548 | + |
549 | + text += self.define_foot() |
550 | + |
551 | + if sym: |
552 | + for elem in self.symmetries: |
553 | + text += self.write_combined_cc(lor_names, elem, |
554 | + compiler_cmd=compiler_cmd, |
555 | + sym=False) |
556 | + |
557 | + |
558 | + if self.out_path: |
559 | + # Prepare a specific file |
560 | + path = os.path.join(os.path.dirname(self.out_path), name+'.f') |
561 | + writer = writers.FortranWriter(path) |
562 | + writer.downcase = False |
563 | + commentstring = 'This File is Automatically generated by ALOHA \n' |
564 | + writer.write_comments(commentstring) |
565 | + writer.writelines(text) |
566 | + |
567 | + return text |
568 | + |
569 | + |
570 | |
571 | - def write(self, mode='self'): |
572 | + def write(self, mode='self', **opt): |
573 | """Write the .h and .cc files""" |
574 | |
575 | - writer_h = writers.CPPWriter(self.out_path + ".h") |
576 | - writer_cc = writers.CPPWriter(self.out_path + ".cc") |
577 | - commentstring = 'This File is Automatically generated by ALOHA \n' |
578 | - commentstring += 'The process calculated in this file is: \n' |
579 | - commentstring += self.comment + '\n' |
580 | - writer_h.write_comments(commentstring) |
581 | - writer_cc.write_comments(commentstring) |
582 | - |
583 | + |
584 | # write head - momenta - body - foot |
585 | - |
586 | header = self.define_header() |
587 | - writer_h.writelines(self.write_h(header)) |
588 | - writer_cc.writelines(self.write_cc(header)) |
589 | - |
590 | + h_text = self.write_h(header, **opt) |
591 | + cc_text = self.write_cc(header, **opt) |
592 | + |
593 | + # write in two file |
594 | + if self.out_path: |
595 | + writer_h = writers.CPPWriter(self.out_path + ".h") |
596 | + writer_cc = writers.CPPWriter(self.out_path + ".cc") |
597 | + commentstring = 'This File is Automatically generated by ALOHA \n' |
598 | + commentstring += 'The process calculated in this file is: \n' |
599 | + commentstring += self.comment + '\n' |
600 | + writer_h.write_comments(commentstring) |
601 | + writer_cc.write_comments(commentstring) |
602 | + writer_h.writelines(h_text) |
603 | + writer_cc.writelines(cc_text) |
604 | + |
605 | + return h_text, cc_text |
606 | + |
607 | + |
608 | + |
609 | + def write_combined(self, lor_names, mode='self', offshell=None, **opt): |
610 | + """Write the .h and .cc files associated to the combined file""" |
611 | + |
612 | + # Set some usefull command |
613 | + if offshell is None: |
614 | + offshell = self.offshell |
615 | + |
616 | + name = combine_name(self.abstractname, lor_names, offshell) |
617 | + |
618 | + h_text = self.write_combined_h(lor_names, offshell, **opt) |
619 | + cc_text = self.write_combined_cc(lor_names, offshell, sym=True, **opt) |
620 | + |
621 | + if self.out_path: |
622 | + # Prepare a specific file |
623 | + path = os.path.join(os.path.dirname(self.out_path), name) |
624 | + commentstring = 'This File is Automatically generated by ALOHA \n' |
625 | + |
626 | + writer_h = writers.CPPWriter(path + ".h") |
627 | + writer_h.write_comments(commentstring) |
628 | + writer_h.writelines(h_text) |
629 | + |
630 | + writer_cc = writers.CPPWriter(path + ".cc") |
631 | + writer_cc.write_comments(commentstring) |
632 | + writer_cc.writelines(cc_text) |
633 | + else: |
634 | + return h_text, cc_text |
635 | + |
636 | + return h_text, cc_text |
637 | + |
638 | class ALOHAWriterForPython(WriteALOHA): |
639 | """ A class for returning a file/a string for python evaluation """ |
640 | |
641 | @@ -723,18 +1016,11 @@ |
642 | """ standard init but if dirpath is None the write routine will |
643 | return a string (which can be evaluated by an exec""" |
644 | |
645 | - if dirpath: |
646 | - WriteALOHA.__init__(self, abstract_routine, dirpath) |
647 | - else: |
648 | - WriteALOHA.__init__(self, abstract_routine, '') |
649 | - self.out_path = None |
650 | - self.dir_out = None |
651 | + WriteALOHA.__init__(self, abstract_routine, dirpath) |
652 | self.outname = '%s%s' % (self.particles[self.offshell -1], \ |
653 | self.offshell) |
654 | |
655 | - |
656 | - |
657 | - |
658 | + |
659 | def change_var_format(self, name): |
660 | """Formatting the variable name to Python format |
661 | start to count at zero""" |
662 | @@ -759,7 +1045,7 @@ |
663 | OutString = '' |
664 | if not self.offshell: |
665 | for ind in self.obj.listindices(): |
666 | - string = 'vertex = C*' + self.write_obj(self.obj.get_rep(ind)) |
667 | + string = 'vertex = COUP*' + self.write_obj(self.obj.get_rep(ind)) |
668 | string = string.replace('+-', '-') |
669 | OutString = OutString + string + '\n' |
670 | else: |
671 | @@ -773,7 +1059,7 @@ |
672 | string = string.replace('+-', '-') |
673 | OutString += string + '\n' |
674 | for ind in numerator.listindices(): |
675 | - string = '%s[%d]= C*denom*' % (self.outname, self.pass_to_HELAS(ind)) |
676 | + string = '%s[%d]= COUP*denom*' % (self.outname, self.pass_to_HELAS(ind)) |
677 | string += self.write_obj(numerator.get_rep(ind)) |
678 | string = string.replace('+-', '-') |
679 | OutString += string + '\n' |
680 | @@ -781,17 +1067,19 @@ |
681 | |
682 | def define_foot(self): |
683 | if not self.offshell: |
684 | - return 'return vertex' |
685 | + return 'return vertex\n\n' |
686 | else: |
687 | - return 'return %s' % (self.outname) |
688 | + return 'return %s\n\n' % (self.outname) |
689 | |
690 | |
691 | - def define_header(self): |
692 | + def define_header(self, name=None): |
693 | """Define the Header of the fortran file. This include |
694 | - function tag |
695 | - definition of variable |
696 | """ |
697 | - |
698 | + if name is None: |
699 | + name = self.namestring |
700 | + |
701 | Momenta = self.collected['momenta'] |
702 | OverM = self.collected['om'] |
703 | |
704 | @@ -801,11 +1089,11 @@ |
705 | # define the type of function and argument |
706 | if not self.offshell: |
707 | str_out += 'def %(name)s(%(args)s):\n' % \ |
708 | - {'name': self.namestring, |
709 | - 'args': ','.join(CallList+ ['C']) } |
710 | + {'name': name, |
711 | + 'args': ','.join(CallList+ ['COUP']) } |
712 | else: |
713 | - str_out += 'def %(name)s(%(args)s, C, M%(id)d, W%(id)d):\n' % \ |
714 | - {'name': self.namestring, |
715 | + str_out += 'def %(name)s(%(args)s, COUP, M%(id)d, W%(id)d):\n' % \ |
716 | + {'name': name, |
717 | 'args': ', '.join(CallList), |
718 | 'id': self.offshell} |
719 | return str_out |
720 | @@ -871,9 +1159,8 @@ |
721 | |
722 | def define_symmetry(self, new_nb): |
723 | number = self.offshell |
724 | - calls = self.reorder_call_list(self.calllist['CallList'], self.offshell, |
725 | - new_nb) |
726 | - Outstring = 'return '+self.namestring+'('+','.join(calls)+',C,M%s,W%s)' \ |
727 | + calls = self.calllist['CallList'] |
728 | + Outstring = 'return '+self.namestring+'('+','.join(calls)+',COUP,M%s,W%s)\n' \ |
729 | %(number,number) |
730 | return Outstring |
731 | |
732 | @@ -900,5 +1187,77 @@ |
733 | |
734 | if self.out_path: |
735 | ff = open(self.out_path,'w').write(text) |
736 | - else: |
737 | - return text |
738 | + |
739 | + return text + '\n' |
740 | + |
741 | + def write_combined(self, lor_names, mode='self', offshell=None): |
742 | + """Write routine for combine ALOHA call (more than one coupling)""" |
743 | + |
744 | + # Set some usefull command |
745 | + if offshell is None: |
746 | + sym = 1 |
747 | + offshell = self.offshell |
748 | + else: |
749 | + sym = None |
750 | + name = combine_name(self.abstractname, lor_names, offshell) |
751 | + |
752 | + # write head - momenta - body - foot |
753 | + text = '' |
754 | + #if mode == 'mg5': |
755 | + # text = 'import aloha.template_files.wavefunctions as wavefunctions\n' |
756 | + #else: |
757 | + # text = 'import wavefunctions\n' |
758 | + |
759 | + |
760 | + # write header |
761 | + header = self.define_header(name=name) |
762 | + new_couplings = ['COUP%s' % (i+1) for i in range(len(lor_names)+1)] |
763 | + header = header.replace('COUP', ','.join(new_couplings)) |
764 | + |
765 | + text += header |
766 | + |
767 | + # Define which part of the routine should be called |
768 | + if 'C' in self.namestring: |
769 | + addon = 'C' +self.namestring.split('C',1)[1] |
770 | + else: |
771 | + addon = '_%s' % self.offshell |
772 | + |
773 | + # how to call the routine |
774 | + if not offshell: |
775 | + main = 'vertex' |
776 | + call_arg = '%(args)s, %(COUP)s' % \ |
777 | + {'args': ', '.join(self.calllist['CallList']), |
778 | + 'COUP':'COUP%d', |
779 | + 'spin': self.particles[self.offshell -1]} |
780 | + else: |
781 | + main = '%(spin)s%(id)d' % \ |
782 | + {'spin': self.particles[self.offshell -1], |
783 | + 'id': self.offshell} |
784 | + call_arg = '%(args)s, %(COUP)s, M%(id)d, W%(id)d' % \ |
785 | + {'args': ', '.join(self.calllist['CallList']), |
786 | + 'COUP':'COUP%d', |
787 | + 'id': self.offshell} |
788 | + |
789 | + # make the first call |
790 | + line = " %s = %s%s("+call_arg+")\n" |
791 | + text += '\n\n' + line % (main, self.namestring, '', 1) |
792 | + |
793 | + # make the other call |
794 | + for i,name in enumerate(lor_names): |
795 | + text += line % ('tmp',name, addon, i+2) |
796 | + if not offshell: |
797 | + text += ' vertex += tmp\n' |
798 | + else: |
799 | + size = self.type_to_size[self.particles[offshell -1]] -2 |
800 | + text += " for i in range(%(id)d):\n" % {'id': size} |
801 | + text += " %(main)s[i] += tmp[i]\n" %{'main': main} |
802 | + |
803 | + text += ' '+self.define_foot() |
804 | + |
805 | + #ADD SYMETRY |
806 | + if sym: |
807 | + for elem in self.symmetries: |
808 | + text += self.write_combined(lor_names, mode, elem) |
809 | + |
810 | + return text |
811 | + |
812 | \ No newline at end of file |
813 | |
814 | === modified file 'aloha/bin/aloha' |
815 | --- aloha/bin/aloha 2011-02-03 09:33:24 +0000 |
816 | +++ aloha/bin/aloha 2011-04-20 16:57:29 +0000 |
817 | @@ -31,7 +31,7 @@ |
818 | |
819 | (options, args) = parser.parse_args() |
820 | if len(args) != 1: |
821 | - sys.exit('ALOHA requires as arguments the path to UFO directory') |
822 | + sys.exit('ALOHA requires exactly one argument (the path to UFO directory)') |
823 | |
824 | # Set logging level according to the logging level given by options |
825 | logging.basicConfig(level=vars(logging)[options.logging]) |
826 | |
827 | === modified file 'aloha/create_aloha.py' |
828 | --- aloha/create_aloha.py 2011-03-31 18:03:05 +0000 |
829 | +++ aloha/create_aloha.py 2011-04-20 16:57:29 +0000 |
830 | @@ -56,18 +56,32 @@ |
831 | self.outgoing = outgoing |
832 | self.infostr = infostr |
833 | self.symmetries = [] |
834 | + self.combined = [] |
835 | |
836 | def add_symmetry(self, outgoing): |
837 | """ add an outgoing """ |
838 | |
839 | if not outgoing in self.symmetries: |
840 | self.symmetries.append(outgoing) |
841 | - |
842 | - def write(self, output_dir, language='Fortran', mode='self'): |
843 | + |
844 | + def add_combine(self, lor_list): |
845 | + """add a combine rule """ |
846 | + |
847 | + if lor_list not in self.combined: |
848 | + self.combined.append(lor_list) |
849 | + |
850 | + def write(self, output_dir, language='Fortran', mode='self', **opt): |
851 | """ write the content of the object """ |
852 | - return getattr(aloha_writers, 'ALOHAWriterFor%s' % language)(self, output_dir).write(mode=mode) |
853 | - |
854 | - |
855 | + |
856 | + writer = getattr(aloha_writers, 'ALOHAWriterFor%s' % language)(self, output_dir) |
857 | + text = writer.write(mode=mode, **opt) |
858 | + for grouped in self.combined: |
859 | + if isinstance(text, tuple): |
860 | + text = tuple([old.__add__(new) for old, new in zip(text, |
861 | + writer.write_combined(grouped, mode=mode, **opt))]) |
862 | + else: |
863 | + text += writer.write_combined(grouped, mode=mode, **opt) |
864 | + return text |
865 | |
866 | class AbstractRoutineBuilder(object): |
867 | """ Launch the creation of the Helicity Routine""" |
868 | @@ -346,6 +360,7 @@ |
869 | # init the dictionary |
870 | dict.__init__(self) |
871 | self.symmetries = {} |
872 | + self.multiple_lor = {} |
873 | |
874 | # check the mass of spin2 (if any) |
875 | self.massless_spin2 = self.has_massless_spin2() |
876 | @@ -394,6 +409,7 @@ |
877 | |
878 | def load(self, filepos=None): |
879 | """ reload the pickle file """ |
880 | + return False |
881 | if not filepos: |
882 | filepos = os.path.join(self.model_pos,'aloha.pkl') |
883 | if os.path.exists(filepos): |
884 | @@ -426,6 +442,7 @@ |
885 | #to compute identical contribution |
886 | self.look_for_symmetries() |
887 | conjugate_list = self.look_for_conjugate() |
888 | + self.look_for_multiple_lorentz_interactions() |
889 | if not wanted_lorentz: |
890 | wanted_lorentz = [l.name for l in self.model.all_lorentz] |
891 | for lorentz in self.model.all_lorentz: |
892 | @@ -445,6 +462,13 @@ |
893 | if 5 in lorentz.spins and self.massless_spin2 is not None: |
894 | builder.spin2_massless = self.massless_spin2 |
895 | self.compute_aloha(builder) |
896 | + |
897 | + if lorentz.name in self.multiple_lor: |
898 | + for m in self.multiple_lor[lorentz.name]: |
899 | + for outgoing in range(len(lorentz.spins)+1): |
900 | + self[(lorentz.name, outgoing)].add_combine(m) |
901 | + |
902 | + |
903 | if lorentz.name in conjugate_list: |
904 | conjg_builder_list= builder.define_all_conjugate_builder(\ |
905 | conjugate_list[lorentz.name]) |
906 | @@ -452,6 +476,11 @@ |
907 | # No duplication of conjugation: |
908 | assert conjg_builder_list.count(conjg_builder) == 1 |
909 | self.compute_aloha(conjg_builder, lorentz.name) |
910 | + if lorentz.name in self.multiple_lor: |
911 | + for m in self.multiple_lor[lorentz.name]: |
912 | + for outgoing in range(len(lorentz.spins)+1): |
913 | + self[(conjg_builder.name, outgoing)].add_combine(m) |
914 | + |
915 | |
916 | |
917 | if save: |
918 | @@ -471,14 +500,16 @@ |
919 | # reorganize the data (in order to use optimization for a given lorentz |
920 | #structure |
921 | request = {} |
922 | - for l_name, conjugate, outgoing in data: |
923 | - try: |
924 | - request[l_name][conjugate].append(outgoing) |
925 | - except: |
926 | + for list_l_name, conjugate, outgoing in data: |
927 | + for l_name in list_l_name: |
928 | try: |
929 | - request[l_name][conjugate] = [outgoing] |
930 | + request[l_name][conjugate].append(outgoing) |
931 | except: |
932 | - request[l_name] = {conjugate: [outgoing]} |
933 | + try: |
934 | + request[l_name][conjugate] = [outgoing] |
935 | + except: |
936 | + request[l_name] = {conjugate: [outgoing]} |
937 | + |
938 | # Loop on the structure to build exactly what is request |
939 | for l_name in request: |
940 | lorentz = eval('self.model.lorentz.%s' % l_name) |
941 | @@ -503,7 +534,14 @@ |
942 | # Compute routines |
943 | self.compute_aloha(conjg_builder, symmetry=lorentz.name, |
944 | routines=routines) |
945 | - |
946 | + |
947 | + # Build mutiple lorentz call |
948 | + for list_l_name, conjugate, outgoing in data: |
949 | + if len(list_l_name) >1: |
950 | + lorentzname = list_l_name[0] |
951 | + for c in conjugate: |
952 | + lorentzname += 'C%s' % c |
953 | + self[(lorentzname, outgoing)].add_combine(list_l_name[1:]) |
954 | |
955 | def compute_aloha(self, builder, symmetry=None, routines=None): |
956 | """ define all the AbstractRoutine linked to a given lorentz structure |
957 | @@ -520,7 +558,7 @@ |
958 | for outgoing in routines: |
959 | symmetric = self.has_symmetries(symmetry, outgoing, valid_output=routines) |
960 | if symmetric: |
961 | - self.get(symmetry, symmetric).add_symmetry(outgoing) |
962 | + self.get(name, symmetric).add_symmetry(outgoing) |
963 | else: |
964 | wavefunction = builder.compute_routine(outgoing) |
965 | #Store the information |
966 | @@ -589,9 +627,9 @@ |
967 | for i, part1 in enumerate(vertex.particles): |
968 | for j in range(i-1,-1,-1): |
969 | part2 = vertex.particles[j] |
970 | - if part1.name == part2.name and \ |
971 | - part1.color == part2.color == 1 and\ |
972 | - part1.spin != 2: |
973 | + if part1.pdg_code == part2.pdg_code: |
974 | + if part1.spin == 2 and (i % 2 != j % 2 ): |
975 | + continue |
976 | for lorentz in vertex.lorentz: |
977 | if self.symmetries.has_key(lorentz.name): |
978 | if self.symmetries[lorentz.name].has_key(i+1): |
979 | @@ -601,7 +639,46 @@ |
980 | else: |
981 | self.symmetries[lorentz.name] = {i+1:j+1} |
982 | break |
983 | + |
984 | + def look_for_multiple_lorentz_interactions(self): |
985 | + """Search the interaction associate with more than one lorentz structure. |
986 | + If those lorentz structure have the same order and the same color then |
987 | + associate a multiple lorentz routines to ALOHA """ |
988 | + |
989 | + orders = {} |
990 | + for coup in self.model.all_couplings: |
991 | + orders[coup.name] = str(coup.order) |
992 | + |
993 | + for vertex in self.model.all_vertices: |
994 | + if len(vertex.lorentz) == 1: |
995 | + continue |
996 | + #remove ghost |
997 | + if -1 in vertex.lorentz[0].spins: |
998 | + continue |
999 | + |
1000 | + # assign each order/color to a set of lorentz routine |
1001 | + combine = {} |
1002 | + for (id_col, id_lor), coup in vertex.couplings.items(): |
1003 | + order = orders[coup.name] |
1004 | + key = (id_col, order) |
1005 | + if key in combine: |
1006 | + combine[key].append(id_lor) |
1007 | + else: |
1008 | + combine[key] = [id_lor] |
1009 | |
1010 | + # Check if more than one routine are associated |
1011 | + for list_lor in combine.values(): |
1012 | + if len(list_lor) == 1: |
1013 | + continue |
1014 | + list_lor.sort() |
1015 | + main = vertex.lorentz[list_lor[0]].name |
1016 | + if main not in self.multiple_lor: |
1017 | + self.multiple_lor[main] = [] |
1018 | + |
1019 | + info = tuple([vertex.lorentz[id].name for id in list_lor[1:]]) |
1020 | + if info not in self.multiple_lor[main]: |
1021 | + self.multiple_lor[main].append(info) |
1022 | + |
1023 | def has_massless_spin2(self): |
1024 | """Search if the spin2 particles are massless or not""" |
1025 | |
1026 | @@ -690,7 +767,7 @@ |
1027 | aloha_files = [] |
1028 | |
1029 | # Identify the valid files |
1030 | - alohafile_pattern = re.compile(r'''^[STFV]*[_C\d]*_\d%s''' % file_ext) |
1031 | + alohafile_pattern = re.compile(r'''^[STFV\d_]*[_C\d]*_\d%s''' % file_ext) |
1032 | for filename in os.listdir(aloha_dir): |
1033 | if os.path.isfile(os.path.join(aloha_dir, filename)): |
1034 | if alohafile_pattern.match(filename): |
1035 | |
1036 | === modified file 'madgraph/core/helas_objects.py' |
1037 | --- madgraph/core/helas_objects.py 2011-04-03 22:06:00 +0000 |
1038 | +++ madgraph/core/helas_objects.py 2011-04-20 16:57:29 +0000 |
1039 | @@ -72,16 +72,16 @@ |
1040 | # interaction_id = the id of the interaction in the model |
1041 | # pdg_codes = the pdg_codes property of the interaction, [11, -11, 22] |
1042 | # inter_color = the 'color' property of the interaction: [] |
1043 | - # lorentz = the 'lorentz' property of the interaction: [''] |
1044 | + # lorentz = the 'lorentz' property of the interaction: ('') |
1045 | # couplings = the coupling names from the interaction: {(0,0):'MGVX12'} |
1046 | self['interaction_id'] = 0 |
1047 | self['pdg_codes'] = [] |
1048 | self['orders'] = {} |
1049 | self['inter_color'] = None |
1050 | - self['lorentz'] = '' |
1051 | - self['coupling'] = 'none' |
1052 | - # The Lorentz and color index used in this wavefunction |
1053 | - self['coupl_key'] = (0, 0) |
1054 | + self['lorentz'] = [] |
1055 | + self['coupling'] = ['none'] |
1056 | + # The color index used in this wavefunction |
1057 | + self['color_key'] = 0 |
1058 | # Properties relating to the leg/vertex |
1059 | # state = initial/final (for external bosons), |
1060 | # intermediate (for intermediate bosons), |
1061 | @@ -206,28 +206,32 @@ |
1062 | "%s is not a valid Color String" % str(value) |
1063 | |
1064 | if name == 'lorentz': |
1065 | - #Should be a string |
1066 | - if not isinstance(value, str): |
1067 | - raise self.PhysicsObjectError, \ |
1068 | - "%s is not a valid string" % str(value) |
1069 | + #Should be a list of string |
1070 | + if not isinstance(value, list): |
1071 | + raise self.PhysicsObjectError, \ |
1072 | + "%s is not a valid tuple" % str(value) |
1073 | + for name in value: |
1074 | + if not isinstance(name, str): |
1075 | + raise self.PhysicsObjectError, \ |
1076 | + "%s doesn't contain only string" % str(value) |
1077 | |
1078 | if name == 'coupling': |
1079 | - #Should be a string |
1080 | - if not isinstance(value, str): |
1081 | - raise self.PhysicsObjectError, \ |
1082 | - "%s is not a valid coupling string" % \ |
1083 | - str(value) |
1084 | + #Should be a list of string |
1085 | + if not isinstance(value, list): |
1086 | + raise self.PhysicsObjectError, \ |
1087 | + "%s is not a valid coupling string" % str(value) |
1088 | + for name in value: |
1089 | + if not isinstance(name, str): |
1090 | + raise self.PhysicsObjectError, \ |
1091 | + "%s doesn't contain only string" % str(value) |
1092 | + if len(value) == 0: |
1093 | + raise self.PhysicsObjectError, \ |
1094 | + "%s should have at least one value" % str(value) |
1095 | |
1096 | - if name == 'coupl_key': |
1097 | - if value and not isinstance(value, tuple): |
1098 | - raise self.PhysicsObjectError, \ |
1099 | - "%s is not a valid tuple" % str(value) |
1100 | - if len(value) != 2: |
1101 | - raise self.PhysicsObjectError, \ |
1102 | - "%s is not a valid tuple with 2 elements" % str(value) |
1103 | - if not isinstance(value[0], int) or not isinstance(value[1], int): |
1104 | - raise self.PhysicsObjectError, \ |
1105 | - "%s is not a valid tuple of integer" % str(value) |
1106 | + if name == 'color_key': |
1107 | + if value and not isinstance(value, int): |
1108 | + raise self.PhysicsObjectError, \ |
1109 | + "%s is not a valid integer" % str(value) |
1110 | |
1111 | if name == 'state': |
1112 | if not isinstance(value, str): |
1113 | @@ -320,9 +324,9 @@ |
1114 | if inter.get('color'): |
1115 | self.set('inter_color', inter.get('color')[0]) |
1116 | if inter.get('lorentz'): |
1117 | - self.set('lorentz', inter.get('lorentz')[0]) |
1118 | + self.set('lorentz', [inter.get('lorentz')[0]]) |
1119 | if inter.get('couplings'): |
1120 | - self.set('coupling', inter.get('couplings').values()[0]) |
1121 | + self.set('coupling', [inter.get('couplings').values()[0]]) |
1122 | return True |
1123 | elif name == 'particle': |
1124 | self.set('particle', model.get('particle_dict')[value]) |
1125 | @@ -343,7 +347,7 @@ |
1126 | |
1127 | return ['particle', 'antiparticle', 'is_part', |
1128 | 'interaction_id', 'pdg_codes', 'orders', 'inter_color', |
1129 | - 'lorentz', 'coupling', 'coupl_key', 'state', 'number_external', |
1130 | + 'lorentz', 'coupling', 'color_key', 'state', 'number_external', |
1131 | 'number', 'fermionflow', 'mothers'] |
1132 | |
1133 | # Helper functions |
1134 | @@ -369,8 +373,8 @@ |
1135 | array_rep = array.array('i', [self['interaction_id']]) |
1136 | # Need the coupling key, to distinguish between |
1137 | # wavefunctions from the same interaction but different |
1138 | - # Lorentz or color structures |
1139 | - array_rep.extend(list(self['coupl_key'])) |
1140 | + # color structures |
1141 | + array_rep.append(self['color_key']) |
1142 | # Finally, the mother numbers |
1143 | array_rep.extend([mother['number'] for \ |
1144 | mother in self['mothers']]) |
1145 | @@ -406,7 +410,7 @@ |
1146 | particles[1].get_anti_pdg_code()\ |
1147 | and self.get('coupling')[0] != '-': |
1148 | # We need a minus sign in front of the coupling |
1149 | - self.set('coupling', '-' + self.get('coupling')) |
1150 | + self.set('coupling', ['-' + c for c in self.get('coupling')]) |
1151 | |
1152 | def set_octet_majorana_coupling_sign(self): |
1153 | """For octet Majorana fermions, need an extra minus sign in |
1154 | @@ -418,7 +422,7 @@ |
1155 | self.get_spin_state_number() == -2 and \ |
1156 | self.get('self_antipart') and \ |
1157 | [m.get('color') for m in self.get('mothers')] == [8, 8]: |
1158 | - self.set('coupling', '-' + self.get('coupling')) |
1159 | + self.set('coupling', ['-' + c for c in self.get('coupling')]) |
1160 | |
1161 | def set_state_and_particle(self, model): |
1162 | """Set incoming/outgoing state according to mother states and |
1163 | @@ -794,7 +798,7 @@ |
1164 | if self.needs_hermitian_conjugate(): |
1165 | res.append(self.get_conjugate_index()) |
1166 | |
1167 | - return (tuple(res), self.get('lorentz')) |
1168 | + return (tuple(res), tuple(self.get('lorentz'))) |
1169 | |
1170 | def get_base_vertices(self, wf_dict = {}, vx_list = [], optimization = 1): |
1171 | """Recursive method to get a base_objects.VertexList |
1172 | @@ -876,7 +880,7 @@ |
1173 | # This is where recursion happens |
1174 | color_indices.extend(mother.get_color_indices()) |
1175 | # Add this wf's color index |
1176 | - color_indices.append(self.get('coupl_key')[0]) |
1177 | + color_indices.append(self.get('color_key')) |
1178 | |
1179 | return color_indices |
1180 | |
1181 | @@ -1058,7 +1062,7 @@ |
1182 | # Check relevant directly defined properties |
1183 | if self['number_external'] != other['number_external'] or \ |
1184 | self['fermionflow'] != other['fermionflow'] or \ |
1185 | - self['coupl_key'] != other['coupl_key'] or \ |
1186 | + self['color_key'] != other['color_key'] or \ |
1187 | self['lorentz'] != other['lorentz'] or \ |
1188 | self['coupling'] != other['coupling'] or \ |
1189 | self['state'] != other['state'] or \ |
1190 | @@ -1293,10 +1297,10 @@ |
1191 | self['pdg_codes'] = [] |
1192 | self['orders'] = {} |
1193 | self['inter_color'] = None |
1194 | - self['lorentz'] = '' |
1195 | - self['coupling'] = 'none' |
1196 | + self['lorentz'] = [] |
1197 | + self['coupling'] = ['none'] |
1198 | # The Lorentz and color index used in this amplitude |
1199 | - self['coupl_key'] = (0, 0) |
1200 | + self['color_key'] = 0 |
1201 | # Properties relating to the vertex |
1202 | self['number'] = 0 |
1203 | self['fermionfactor'] = 0 |
1204 | @@ -1359,28 +1363,33 @@ |
1205 | "%s is not a valid Color String" % str(value) |
1206 | |
1207 | if name == 'lorentz': |
1208 | - #Should be a string |
1209 | - if not isinstance(value, str): |
1210 | - raise self.PhysicsObjectError, \ |
1211 | - "%s is not a valid string" % str(value) |
1212 | - |
1213 | + #Should be a list of string |
1214 | + if not isinstance(value, list): |
1215 | + raise self.PhysicsObjectError, \ |
1216 | + "%s is not a valid list of string" % str(value) |
1217 | + for name in value: |
1218 | + if not isinstance(name, str): |
1219 | + raise self.PhysicsObjectError, \ |
1220 | + "%s doesn't contain only string" % str(value) |
1221 | + |
1222 | if name == 'coupling': |
1223 | - #Should be a string |
1224 | - if not isinstance(value, str): |
1225 | - raise self.PhysicsObjectError, \ |
1226 | - "%s is not a valid coupling string" % \ |
1227 | - str(value) |
1228 | + #Should be a list of string |
1229 | + if not isinstance(value, list): |
1230 | + raise self.PhysicsObjectError, \ |
1231 | + "%s is not a valid coupling (list of string)" % str(value) |
1232 | + |
1233 | + for name in value: |
1234 | + if not isinstance(name, str): |
1235 | + raise self.PhysicsObjectError, \ |
1236 | + "%s doesn't contain only string" % str(value) |
1237 | + if not len(value): |
1238 | + raise self.PhysicsObjectError, \ |
1239 | + 'coupling should have at least one value' |
1240 | |
1241 | - if name == 'coupl_key': |
1242 | - if value and not isinstance(value, tuple): |
1243 | - raise self.PhysicsObjectError, \ |
1244 | - "%s is not a valid tuple" % str(value) |
1245 | - if len(value) != 2: |
1246 | - raise self.PhysicsObjectError, \ |
1247 | - "%s is not a valid tuple with 2 elements" % str(value) |
1248 | - if not isinstance(value[0], int) or not isinstance(value[1], int): |
1249 | - raise self.PhysicsObjectError, \ |
1250 | - "%s is not a valid tuple of integer" % str(value) |
1251 | + if name == 'color_key': |
1252 | + if value and not isinstance(value, int): |
1253 | + raise self.PhysicsObjectError, \ |
1254 | + "%s is not a valid integer" % str(value) |
1255 | |
1256 | if name == 'number': |
1257 | if not isinstance(value, int): |
1258 | @@ -1416,6 +1425,30 @@ |
1259 | |
1260 | return True |
1261 | |
1262 | + def __str__(self): |
1263 | + """ practicle way to represent an HelasAmplitude""" |
1264 | + |
1265 | + mystr = '{\n' |
1266 | + for prop in self.get_sorted_keys(): |
1267 | + if isinstance(self[prop], str): |
1268 | + mystr = mystr + ' \'' + prop + '\': \'' + \ |
1269 | + self[prop] + '\',\n' |
1270 | + elif isinstance(self[prop], float): |
1271 | + mystr = mystr + ' \'' + prop + '\': %.2f,\n' % self[prop] |
1272 | + elif isinstance(self[prop], int): |
1273 | + mystr = mystr + ' \'' + prop + '\': %s,\n' % self[prop] |
1274 | + elif prop != 'mothers': |
1275 | + mystr = mystr + ' \'' + prop + '\': ' + \ |
1276 | + str(self[prop]) + ',\n' |
1277 | + else: |
1278 | + info = [m.get('pdg_code') for m in self['mothers']] |
1279 | + mystr += ' \'%s\': %s,\n' % (prop, info) |
1280 | + |
1281 | + mystr = mystr.rstrip(',\n') |
1282 | + mystr = mystr + '\n}' |
1283 | + |
1284 | + return mystr |
1285 | + |
1286 | # Enhanced get function |
1287 | def get(self, name): |
1288 | """Get the value of the property name.""" |
1289 | @@ -1453,9 +1486,9 @@ |
1290 | if inter.get('color'): |
1291 | self.set('inter_color', inter.get('color')[0]) |
1292 | if inter.get('lorentz'): |
1293 | - self.set('lorentz', inter.get('lorentz')[0]) |
1294 | + self.set('lorentz', [inter.get('lorentz')[0]]) |
1295 | if inter.get('couplings'): |
1296 | - self.set('coupling', inter.get('couplings').values()[0]) |
1297 | + self.set('coupling', [inter.get('couplings').values()[0]]) |
1298 | return True |
1299 | else: |
1300 | raise self.PhysicsObjectError, \ |
1301 | @@ -1467,7 +1500,7 @@ |
1302 | """Return particle property names as a nicely sorted list.""" |
1303 | |
1304 | return ['interaction_id', 'pdg_codes', 'orders', 'inter_color', |
1305 | - 'lorentz', 'coupling', 'coupl_key', 'number', 'color_indices', |
1306 | + 'lorentz', 'coupling', 'color_key', 'number', 'color_indices', |
1307 | 'fermionfactor', 'mothers'] |
1308 | |
1309 | |
1310 | @@ -1516,7 +1549,7 @@ |
1311 | if self.needs_hermitian_conjugate(): |
1312 | res.append(self.get_conjugate_index()) |
1313 | |
1314 | - return (tuple(res), self.get('lorentz')) |
1315 | + return (tuple(res), tuple(self.get('lorentz'))) |
1316 | |
1317 | def calculate_fermionfactor(self): |
1318 | """Calculate the fermion factor for the diagram corresponding |
1319 | @@ -1770,7 +1803,7 @@ |
1320 | |
1321 | # Add this amp's color index |
1322 | if self.get('interaction_id'): |
1323 | - color_indices.append(self.get('coupl_key')[0]) |
1324 | + color_indices.append(self.get('color_key')) |
1325 | |
1326 | return color_indices |
1327 | |
1328 | @@ -2218,15 +2251,22 @@ |
1329 | |
1330 | # Now generate new wavefunction for the last leg |
1331 | |
1332 | - # Need one amplitude for each Lorentz/color structure, |
1333 | - # i.e. for each coupling |
1334 | + # Need one amplitude for each color structure, |
1335 | + done_color = {} # store link to color |
1336 | for coupl_key in sorted(inter.get('couplings').keys()): |
1337 | + color = coupl_key[0] |
1338 | + if color in done_color: |
1339 | + wf = done_color[color] |
1340 | + wf.get('coupling').append(inter.get('couplings')[coupl_key]) |
1341 | + wf.get('lorentz').append(inter.get('lorentz')[coupl_key[1]]) |
1342 | + continue |
1343 | wf = HelasWavefunction(last_leg, vertex.get('id'), model) |
1344 | - wf.set('coupling', inter.get('couplings')[coupl_key]) |
1345 | + wf.set('coupling', [inter.get('couplings')[coupl_key]]) |
1346 | if inter.get('color'): |
1347 | wf.set('inter_color', inter.get('color')[coupl_key[0]]) |
1348 | - wf.set('lorentz', inter.get('lorentz')[coupl_key[1]]) |
1349 | - wf.set('coupl_key', coupl_key) |
1350 | + done_color[color] = wf |
1351 | + wf.set('lorentz', [inter.get('lorentz')[coupl_key[1]]]) |
1352 | + wf.set('color_key', color) |
1353 | wf.set('mothers', mothers) |
1354 | # Need to set incoming/outgoing and |
1355 | # particle/antiparticle according to the fermion flow |
1356 | @@ -2312,24 +2352,29 @@ |
1357 | wf_number, |
1358 | False, |
1359 | number_to_wavefunctions) |
1360 | - |
1361 | + done_color = {} |
1362 | for i, coupl_key in enumerate(keys): |
1363 | + color = coupl_key[0] |
1364 | + if inter and color in done_color.keys(): |
1365 | + amp = done_color[color] |
1366 | + amp.get('coupling').append(inter.get('couplings')[coupl_key]) |
1367 | + amp.get('lorentz').append(inter.get('lorentz')[coupl_key[1]]) |
1368 | + continue |
1369 | amp = HelasAmplitude(lastvx, model) |
1370 | if inter: |
1371 | - amp.set('coupling', inter.get('couplings')[coupl_key]) |
1372 | - amp.set('lorentz', inter.get('lorentz')[\ |
1373 | - coupl_key[1]]) |
1374 | + amp.set('coupling', [inter.get('couplings')[coupl_key]]) |
1375 | + amp.set('lorentz', [inter.get('lorentz')[coupl_key[1]]]) |
1376 | if inter.get('color'): |
1377 | - amp.set('inter_color', inter.get('color')[\ |
1378 | - coupl_key[0]]) |
1379 | - amp.set('coupl_key', coupl_key) |
1380 | + amp.set('inter_color', inter.get('color')[color]) |
1381 | + amp.set('color_key', color) |
1382 | + done_color[color] = amp |
1383 | amp.set('mothers', mothers) |
1384 | amplitude_number = amplitude_number + 1 |
1385 | amp.set('number', amplitude_number) |
1386 | # Add the list with color indices to the amplitude |
1387 | new_color_list = copy.copy(color_list) |
1388 | if inter: |
1389 | - new_color_list.append(coupl_key[0]) |
1390 | + new_color_list.append(color) |
1391 | |
1392 | amp.set('color_indices', new_color_list) |
1393 | |
1394 | @@ -3291,7 +3336,7 @@ |
1395 | """Return a list of (lorentz_name, conjugate, outgoing) with |
1396 | all lorentz structures used by this HelasMatrixElement.""" |
1397 | |
1398 | - return [(wa.get('lorentz'), tuple(wa.get_conjugate_index()), |
1399 | + return [(tuple(wa.get('lorentz')), tuple(wa.get_conjugate_index()), |
1400 | wa.find_outgoing_number()) for wa in \ |
1401 | self.get_all_wavefunctions() + self.get_all_amplitudes() \ |
1402 | if wa.get('interaction_id') != 0] |
1403 | @@ -3967,7 +4012,7 @@ |
1404 | coupling_list = [] |
1405 | |
1406 | for me in self.get('matrix_elements'): |
1407 | - coupling_list.extend(me.get_used_couplings()) |
1408 | + coupling_list.extend([c for l in me.get_used_couplings() for c in l]) |
1409 | |
1410 | return list(set(coupling_list)) |
1411 | |
1412 | |
1413 | === modified file 'madgraph/interface/cmd_interface.py' |
1414 | --- madgraph/interface/cmd_interface.py 2011-04-20 13:10:25 +0000 |
1415 | +++ madgraph/interface/cmd_interface.py 2011-04-20 16:57:29 +0000 |
1416 | @@ -2443,7 +2443,6 @@ |
1417 | raise self.InvalidCmd , '%s cannot be run from MG5 interface' % args[0] |
1418 | |
1419 | |
1420 | - |
1421 | ext_program.run() |
1422 | |
1423 | |
1424 | |
1425 | === modified file 'madgraph/iolibs/export_cpp.py' |
1426 | --- madgraph/iolibs/export_cpp.py 2011-04-15 19:21:44 +0000 |
1427 | +++ madgraph/iolibs/export_cpp.py 2011-04-20 16:57:29 +0000 |
1428 | @@ -232,7 +232,10 @@ |
1429 | else: |
1430 | self.process_string = self.processes[0].base_string() |
1431 | |
1432 | - self.process_number = process_number |
1433 | + if process_number: |
1434 | + self.process_number = process_number |
1435 | + else: |
1436 | + self.process_number = self.processes[0].get('id') |
1437 | |
1438 | self.process_name = self.get_process_name() |
1439 | self.process_class = "CPPProcess" |
1440 | @@ -1881,14 +1884,21 @@ |
1441 | aloha_model.compute_subset(self.wanted_lorentz) |
1442 | else: |
1443 | aloha_model.compute_all(save=False) |
1444 | + |
1445 | for abstracthelas in dict(aloha_model).values(): |
1446 | - aloha_writer = aloha_writers.ALOHAWriterForCPP(abstracthelas, |
1447 | - self.dir_path) |
1448 | - header = aloha_writer.define_header() |
1449 | - template_h_files.append(self.write_function_declaration(\ |
1450 | - aloha_writer, header)) |
1451 | - template_cc_files.append(self.write_function_definition(\ |
1452 | - aloha_writer, header)) |
1453 | + h_rout, cc_rout = abstracthelas.write(output_dir=None, language='CPP', |
1454 | + compiler_cmd=False) |
1455 | + |
1456 | + template_h_files.append(h_rout) |
1457 | + template_cc_files.append(cc_rout) |
1458 | + |
1459 | + #aloha_writer = aloha_writers.ALOHAWriterForCPP(abstracthelas, |
1460 | + # self.dir_path) |
1461 | + #header = aloha_writer.define_header() |
1462 | + #template_h_files.append(self.write_function_declaration(\ |
1463 | + # aloha_writer, header)) |
1464 | + #template_cc_files.append(self.write_function_definition(\ |
1465 | + # aloha_writer, header)) |
1466 | |
1467 | replace_dict['function_declarations'] = '\n'.join(template_h_files) |
1468 | replace_dict['function_definitions'] = '\n'.join(template_cc_files) |
1469 | @@ -1928,27 +1938,27 @@ |
1470 | |
1471 | return template_files |
1472 | |
1473 | - def write_function_declaration(self, aloha_writer, header): |
1474 | - """Write the function declaration for the ALOHA routine""" |
1475 | - |
1476 | - ret_lines = [] |
1477 | - for line in aloha_writer.write_h(header).split('\n'): |
1478 | - if self.compiler_option_re.match(line) or self.namespace_re.match(line): |
1479 | - # Strip out compiler flags and namespaces |
1480 | - continue |
1481 | - ret_lines.append(line) |
1482 | - return "\n".join(ret_lines) |
1483 | - |
1484 | - def write_function_definition(self, aloha_writer, header): |
1485 | - """Write the function definition for the ALOHA routine""" |
1486 | - |
1487 | - ret_lines = [] |
1488 | - for line in aloha_writer.write_cc(header).split('\n'): |
1489 | - if self.compiler_option_re.match(line) or self.namespace_re.match(line): |
1490 | - # Strip out compiler flags and namespaces |
1491 | - continue |
1492 | - ret_lines.append(line) |
1493 | - return "\n".join(ret_lines) |
1494 | +# def write_function_declaration(self, aloha_writer, header): |
1495 | +# """Write the function declaration for the ALOHA routine""" |
1496 | +# |
1497 | +# ret_lines = [] |
1498 | +# for line in aloha_writer.write_h(header).split('\n'): |
1499 | +# if self.compiler_option_re.match(line) or self.namespace_re.match(line): |
1500 | +# # Strip out compiler flags and namespaces |
1501 | +# continue |
1502 | +# ret_lines.append(line) |
1503 | +# return "\n".join(ret_lines) |
1504 | +# |
1505 | +# def write_function_definition(self, aloha_writer, header): |
1506 | +# """Write the function definition for the ALOHA routine""" |
1507 | +# |
1508 | +# ret_lines = [] |
1509 | +# for line in aloha_writer.write_cc(header).split('\n'): |
1510 | +# if self.compiler_option_re.match(line) or self.namespace_re.match(line): |
1511 | +# # Strip out compiler flags and namespaces |
1512 | +# continue |
1513 | +# ret_lines.append(line) |
1514 | +# return "\n".join(ret_lines) |
1515 | |
1516 | def clean_line(self, line): |
1517 | """Strip a line of compiler options and namespace options.""" |
1518 | |
1519 | === modified file 'madgraph/iolibs/export_python.py' |
1520 | --- madgraph/iolibs/export_python.py 2010-12-01 01:33:28 +0000 |
1521 | +++ madgraph/iolibs/export_python.py 2011-04-20 16:57:29 +0000 |
1522 | @@ -354,10 +354,12 @@ |
1523 | parameters.remove('ZERO') |
1524 | |
1525 | # Get all couplings used |
1526 | - couplings = list(set([func.get('coupling').replace('-', '') for func \ |
1527 | + |
1528 | + |
1529 | + couplings = list(set([c.replace('-', '') for func \ |
1530 | in matrix_element.get_all_wavefunctions() + \ |
1531 | - matrix_element.get_all_amplitudes() |
1532 | - if func.get('mothers')])) |
1533 | + matrix_element.get_all_amplitudes() for c in func.get('coupling') |
1534 | + if func.get('mothers') ])) |
1535 | |
1536 | return "\n ".join([\ |
1537 | "%(param)s = model.get(\'parameter_dict\')[\"%(param)s\"]"\ |
1538 | |
1539 | === modified file 'madgraph/iolibs/export_v4.py' |
1540 | --- madgraph/iolibs/export_v4.py 2011-04-18 15:25:50 +0000 |
1541 | +++ madgraph/iolibs/export_v4.py 2011-04-20 16:57:29 +0000 |
1542 | @@ -2477,11 +2477,6 @@ |
1543 | double complex gal(2) |
1544 | common/weak/ gal |
1545 | |
1546 | - double precision DUM0 |
1547 | - common/FRDUM0/ DUM0 |
1548 | - |
1549 | - double precision DUM1 |
1550 | - common/FRDUM1/ DUM1 |
1551 | """ |
1552 | fsock.writelines(header) |
1553 | |
1554 | @@ -2587,10 +2582,6 @@ |
1555 | gal(2) = 1d0 |
1556 | """) |
1557 | |
1558 | - fsock.write_comments("\nDefinition of DUM symbols\n") |
1559 | - fsock.writelines(""" DUM0 = 0 |
1560 | - DUM1 = 1 |
1561 | - """) |
1562 | |
1563 | def create_couplings(self): |
1564 | """ create couplings.f and all couplingsX.f """ |
1565 | |
1566 | === modified file 'madgraph/iolibs/helas_call_writers.py' |
1567 | --- madgraph/iolibs/helas_call_writers.py 2011-03-31 18:03:05 +0000 |
1568 | +++ madgraph/iolibs/helas_call_writers.py 2011-04-20 16:57:29 +0000 |
1569 | @@ -16,6 +16,7 @@ |
1570 | |
1571 | import madgraph.core.base_objects as base_objects |
1572 | import madgraph.core.helas_objects as helas_objects |
1573 | +import aloha.aloha_writers as aloha_writers |
1574 | from madgraph import MadGraph5Error |
1575 | |
1576 | |
1577 | @@ -224,210 +225,210 @@ |
1578 | |
1579 | # Gluon 4-vertex division tensor calls ggT for the FR sm and mssm |
1580 | |
1581 | - key = ((3, 3, 5, 3), 'A') |
1582 | + key = ((3, 3, 5, 3), ('A',)) |
1583 | call = lambda wf: \ |
1584 | "CALL UVVAXX(W(1,%d),W(1,%d),%s,zero,zero,zero,W(1,%d))" % \ |
1585 | (FortranHelasCallWriter.sorted_mothers(wf)[0].get('number'), |
1586 | FortranHelasCallWriter.sorted_mothers(wf)[1].get('number'), |
1587 | - wf.get('coupling'), |
1588 | + wf.get('coupling')[0], |
1589 | wf.get('number')) |
1590 | self.add_wavefunction(key, call) |
1591 | |
1592 | - key = ((3, 5, 3, 1), 'A') |
1593 | + key = ((3, 5, 3, 1), ('A',)) |
1594 | call = lambda wf: \ |
1595 | "CALL JVTAXX(W(1,%d),W(1,%d),%s,zero,zero,W(1,%d))" % \ |
1596 | (FortranHelasCallWriter.sorted_mothers(wf)[0].get('number'), |
1597 | FortranHelasCallWriter.sorted_mothers(wf)[1].get('number'), |
1598 | - wf.get('coupling'), |
1599 | + wf.get('coupling')[0], |
1600 | wf.get('number')) |
1601 | self.add_wavefunction(key, call) |
1602 | |
1603 | - key = ((3, 3, 5), 'A') |
1604 | + key = ((3, 3, 5), ('A',)) |
1605 | call = lambda amp: \ |
1606 | "CALL VVTAXX(W(1,%d),W(1,%d),W(1,%d),%s,zero,AMP(%d))" % \ |
1607 | (FortranHelasCallWriter.sorted_mothers(amp)[0].get('number'), |
1608 | FortranHelasCallWriter.sorted_mothers(amp)[1].get('number'), |
1609 | FortranHelasCallWriter.sorted_mothers(amp)[2].get('number'), |
1610 | - amp.get('coupling'), |
1611 | + amp.get('coupling')[0], |
1612 | amp.get('number')) |
1613 | self.add_amplitude(key, call) |
1614 | |
1615 | # SM gluon 4-vertex components |
1616 | |
1617 | - key = ((3, 3, 3, 3, 1), 'gggg3') |
1618 | + key = ((3, 3, 3, 3, 1), ('gggg3',)) |
1619 | call = lambda wf: \ |
1620 | "CALL JGGGXX(W(1,%d),W(1,%d),W(1,%d),%s,W(1,%d))" % \ |
1621 | (FortranHelasCallWriter.sorted_mothers(wf)[1].get('number'), |
1622 | FortranHelasCallWriter.sorted_mothers(wf)[0].get('number'), |
1623 | FortranHelasCallWriter.sorted_mothers(wf)[2].get('number'), |
1624 | - wf.get('coupling'), |
1625 | + wf.get('coupling')[0], |
1626 | wf.get('number')) |
1627 | self.add_wavefunction(key, call) |
1628 | - key = ((3, 3, 3, 3), 'gggg1') |
1629 | + key = ((3, 3, 3, 3), ('gggg1',)) |
1630 | call = lambda amp: \ |
1631 | "CALL GGGGXX(W(1,%d),W(1,%d),W(1,%d),W(1,%d),%s,AMP(%d))" % \ |
1632 | (FortranHelasCallWriter.sorted_mothers(amp)[0].get('number'), |
1633 | FortranHelasCallWriter.sorted_mothers(amp)[1].get('number'), |
1634 | FortranHelasCallWriter.sorted_mothers(amp)[2].get('number'), |
1635 | FortranHelasCallWriter.sorted_mothers(amp)[3].get('number'), |
1636 | - amp.get('coupling'), |
1637 | + amp.get('coupling')[0], |
1638 | amp.get('number')) |
1639 | self.add_amplitude(key, call) |
1640 | - key = ((3, 3, 3, 3, 1), 'gggg2') |
1641 | + key = ((3, 3, 3, 3, 1), ('gggg2',)) |
1642 | call = lambda wf: \ |
1643 | "CALL JGGGXX(W(1,%d),W(1,%d),W(1,%d),%s,W(1,%d))" % \ |
1644 | (FortranHelasCallWriter.sorted_mothers(wf)[0].get('number'), |
1645 | FortranHelasCallWriter.sorted_mothers(wf)[2].get('number'), |
1646 | FortranHelasCallWriter.sorted_mothers(wf)[1].get('number'), |
1647 | - wf.get('coupling'), |
1648 | + wf.get('coupling')[0], |
1649 | wf.get('number')) |
1650 | self.add_wavefunction(key, call) |
1651 | - key = ((3, 3, 3, 3), 'gggg2') |
1652 | + key = ((3, 3, 3, 3), ('gggg2',)) |
1653 | call = lambda amp: \ |
1654 | "CALL GGGGXX(W(1,%d),W(1,%d),W(1,%d),W(1,%d),%s,AMP(%d))" % \ |
1655 | (FortranHelasCallWriter.sorted_mothers(amp)[2].get('number'), |
1656 | FortranHelasCallWriter.sorted_mothers(amp)[0].get('number'), |
1657 | FortranHelasCallWriter.sorted_mothers(amp)[1].get('number'), |
1658 | FortranHelasCallWriter.sorted_mothers(amp)[3].get('number'), |
1659 | - amp.get('coupling'), |
1660 | + amp.get('coupling')[0], |
1661 | amp.get('number')) |
1662 | self.add_amplitude(key, call) |
1663 | - key = ((3, 3, 3, 3, 1), 'gggg1') |
1664 | + key = ((3, 3, 3, 3, 1), ('gggg1',)) |
1665 | call = lambda wf: \ |
1666 | "CALL JGGGXX(W(1,%d),W(1,%d),W(1,%d),%s,W(1,%d))" % \ |
1667 | (FortranHelasCallWriter.sorted_mothers(wf)[2].get('number'), |
1668 | FortranHelasCallWriter.sorted_mothers(wf)[1].get('number'), |
1669 | FortranHelasCallWriter.sorted_mothers(wf)[0].get('number'), |
1670 | - wf.get('coupling'), |
1671 | + wf.get('coupling')[0], |
1672 | wf.get('number')) |
1673 | self.add_wavefunction(key, call) |
1674 | - key = ((3, 3, 3, 3), 'gggg3') |
1675 | + key = ((3, 3, 3, 3), ('gggg3',)) |
1676 | call = lambda amp: \ |
1677 | "CALL GGGGXX(W(1,%d),W(1,%d),W(1,%d),W(1,%d),%s,AMP(%d))" % \ |
1678 | (FortranHelasCallWriter.sorted_mothers(amp)[1].get('number'), |
1679 | FortranHelasCallWriter.sorted_mothers(amp)[2].get('number'), |
1680 | FortranHelasCallWriter.sorted_mothers(amp)[0].get('number'), |
1681 | FortranHelasCallWriter.sorted_mothers(amp)[3].get('number'), |
1682 | - amp.get('coupling'), |
1683 | - amp.get('number')) |
1684 | - self.add_amplitude(key, call) |
1685 | - |
1686 | - # HEFT VVVS calls |
1687 | - |
1688 | - key = ((1, 3, 3, 3, 3), '') |
1689 | - call = lambda wf: \ |
1690 | - "CALL JVVSXX(W(1,%d),W(1,%d),W(1,%d),DUM1,%s,%s,%s,W(1,%d))" % \ |
1691 | - (wf.get('mothers')[0].get('number'), |
1692 | - wf.get('mothers')[1].get('number'), |
1693 | - wf.get('mothers')[2].get('number'), |
1694 | - wf.get('coupling'), |
1695 | - wf.get('mass'), |
1696 | - wf.get('width'), |
1697 | - wf.get('number')) |
1698 | - self.add_wavefunction(key, call) |
1699 | - |
1700 | - key = ((3, 3, 3, 1, 4), '') |
1701 | - call = lambda wf: \ |
1702 | - "CALL HVVVXX(W(1,%d),W(1,%d),W(1,%d),DUM1,%s,%s,%s,W(1,%d))" % \ |
1703 | - (wf.get('mothers')[0].get('number'), |
1704 | - wf.get('mothers')[1].get('number'), |
1705 | - wf.get('mothers')[2].get('number'), |
1706 | - wf.get('coupling'), |
1707 | - wf.get('mass'), |
1708 | - wf.get('width'), |
1709 | - wf.get('number')) |
1710 | - self.add_wavefunction(key, call) |
1711 | - |
1712 | - key = ((1, 3, 3, 3), '') |
1713 | - call = lambda amp: \ |
1714 | - "CALL VVVSXX(W(1,%d),W(1,%d),W(1,%d),W(1,%d),DUM1,%s,AMP(%d))" % \ |
1715 | - (amp.get('mothers')[0].get('number'), |
1716 | - amp.get('mothers')[1].get('number'), |
1717 | - amp.get('mothers')[2].get('number'), |
1718 | - amp.get('mothers')[3].get('number'), |
1719 | - amp.get('coupling'), |
1720 | - amp.get('number')) |
1721 | - self.add_amplitude(key, call) |
1722 | - |
1723 | - # HEFT VVVS calls |
1724 | - |
1725 | - key = ((1, 3, 3, 3, 1), '') |
1726 | - call = lambda wf: \ |
1727 | - "CALL JVVSXX(W(1,%d),W(1,%d),W(1,%d),DUM1,%s,%s,%s,W(1,%d))" % \ |
1728 | - (wf.get('mothers')[0].get('number'), |
1729 | - wf.get('mothers')[1].get('number'), |
1730 | - wf.get('mothers')[2].get('number'), |
1731 | - wf.get('coupling'), |
1732 | - wf.get('mass'), |
1733 | - wf.get('width'), |
1734 | - wf.get('number')) |
1735 | - self.add_wavefunction(key, call) |
1736 | - |
1737 | - key = ((3, 3, 3, 1, 4), '') |
1738 | - call = lambda wf: \ |
1739 | - "CALL HVVVXX(W(1,%d),W(1,%d),W(1,%d),DUM1,%s,%s,%s,W(1,%d))" % \ |
1740 | - (wf.get('mothers')[0].get('number'), |
1741 | - wf.get('mothers')[1].get('number'), |
1742 | - wf.get('mothers')[2].get('number'), |
1743 | - wf.get('coupling'), |
1744 | - wf.get('mass'), |
1745 | - wf.get('width'), |
1746 | - wf.get('number')) |
1747 | - self.add_wavefunction(key, call) |
1748 | - |
1749 | - key = ((1, 3, 3, 3), '') |
1750 | - call = lambda amp: \ |
1751 | - "CALL VVVSXX(W(1,%d),W(1,%d),W(1,%d),W(1,%d),DUM1,%s,AMP(%d))" % \ |
1752 | - (amp.get('mothers')[0].get('number'), |
1753 | - amp.get('mothers')[1].get('number'), |
1754 | - amp.get('mothers')[2].get('number'), |
1755 | - amp.get('mothers')[3].get('number'), |
1756 | - amp.get('coupling'), |
1757 | + amp.get('coupling')[0], |
1758 | + amp.get('number')) |
1759 | + self.add_amplitude(key, call) |
1760 | + |
1761 | + # HEFT VVVS calls |
1762 | + |
1763 | + key = ((1, 3, 3, 3, 3), ('',)) |
1764 | + call = lambda wf: \ |
1765 | + "CALL JVVSXX(W(1,%d),W(1,%d),W(1,%d),DUM1,%s,%s,%s,W(1,%d))" % \ |
1766 | + (wf.get('mothers')[0].get('number'), |
1767 | + wf.get('mothers')[1].get('number'), |
1768 | + wf.get('mothers')[2].get('number'), |
1769 | + wf.get('coupling')[0], |
1770 | + wf.get('mass'), |
1771 | + wf.get('width'), |
1772 | + wf.get('number')) |
1773 | + self.add_wavefunction(key, call) |
1774 | + |
1775 | + key = ((3, 3, 3, 1, 4), ('',)) |
1776 | + call = lambda wf: \ |
1777 | + "CALL HVVVXX(W(1,%d),W(1,%d),W(1,%d),DUM1,%s,%s,%s,W(1,%d))" % \ |
1778 | + (wf.get('mothers')[0].get('number'), |
1779 | + wf.get('mothers')[1].get('number'), |
1780 | + wf.get('mothers')[2].get('number'), |
1781 | + wf.get('coupling')[0], |
1782 | + wf.get('mass'), |
1783 | + wf.get('width'), |
1784 | + wf.get('number')) |
1785 | + self.add_wavefunction(key, call) |
1786 | + |
1787 | + key = ((1, 3, 3, 3), ('',)) |
1788 | + call = lambda amp: \ |
1789 | + "CALL VVVSXX(W(1,%d),W(1,%d),W(1,%d),W(1,%d),DUM1,%s,AMP(%d))" % \ |
1790 | + (amp.get('mothers')[0].get('number'), |
1791 | + amp.get('mothers')[1].get('number'), |
1792 | + amp.get('mothers')[2].get('number'), |
1793 | + amp.get('mothers')[3].get('number'), |
1794 | + amp.get('coupling')[0], |
1795 | + amp.get('number')) |
1796 | + self.add_amplitude(key, call) |
1797 | + |
1798 | + # HEFT VVVS calls |
1799 | + |
1800 | + key = ((1, 3, 3, 3, 1), ('',)) |
1801 | + call = lambda wf: \ |
1802 | + "CALL JVVSXX(W(1,%d),W(1,%d),W(1,%d),DUM1,%s,%s,%s,W(1,%d))" % \ |
1803 | + (wf.get('mothers')[0].get('number'), |
1804 | + wf.get('mothers')[1].get('number'), |
1805 | + wf.get('mothers')[2].get('number'), |
1806 | + wf.get('coupling')[0], |
1807 | + wf.get('mass'), |
1808 | + wf.get('width'), |
1809 | + wf.get('number')) |
1810 | + self.add_wavefunction(key, call) |
1811 | + |
1812 | + key = ((3, 3, 3, 1, 4), ('',)) |
1813 | + call = lambda wf: \ |
1814 | + "CALL HVVVXX(W(1,%d),W(1,%d),W(1,%d),DUM1,%s,%s,%s,W(1,%d))" % \ |
1815 | + (wf.get('mothers')[0].get('number'), |
1816 | + wf.get('mothers')[1].get('number'), |
1817 | + wf.get('mothers')[2].get('number'), |
1818 | + wf.get('coupling')[0], |
1819 | + wf.get('mass'), |
1820 | + wf.get('width'), |
1821 | + wf.get('number')) |
1822 | + self.add_wavefunction(key, call) |
1823 | + |
1824 | + key = ((1, 3, 3, 3), ('',)) |
1825 | + call = lambda amp: \ |
1826 | + "CALL VVVSXX(W(1,%d),W(1,%d),W(1,%d),W(1,%d),DUM1,%s,AMP(%d))" % \ |
1827 | + (amp.get('mothers')[0].get('number'), |
1828 | + amp.get('mothers')[1].get('number'), |
1829 | + amp.get('mothers')[2].get('number'), |
1830 | + amp.get('mothers')[3].get('number'), |
1831 | + amp.get('coupling')[0], |
1832 | amp.get('number')) |
1833 | self.add_amplitude(key, call) |
1834 | |
1835 | # Spin2 Helas Routine |
1836 | - key = ((-2, 2, 5), '') |
1837 | + key = ((-2, 2, 5), ('',)) |
1838 | call = lambda amp: \ |
1839 | "CALL IOTXXX(W(1,%d),W(1,%d),W(1,%d),%s,%s,AMP(%d))" % \ |
1840 | (amp.get('mothers')[0].get('number'), |
1841 | amp.get('mothers')[1].get('number'), |
1842 | amp.get('mothers')[2].get('number'), |
1843 | - amp.get('coupling'), |
1844 | + amp.get('coupling')[0], |
1845 | amp.get('mothers')[0].get('mass'), |
1846 | amp.get('number')) |
1847 | self.add_amplitude(key, call) |
1848 | |
1849 | - key = ((-2, 2, 5, 3), '') |
1850 | + key = ((-2, 2, 5, 3), ('',)) |
1851 | call = lambda wf: \ |
1852 | "CALL UIOXXX(W(1,%d),W(1,%d),%s,%s,%s,%s,W(1,%d))" % \ |
1853 | (wf.get('mothers')[0].get('number'), |
1854 | wf.get('mothers')[1].get('number'), |
1855 | - wf.get('coupling'), |
1856 | + wf.get('coupling')[0], |
1857 | wf.get('mothers')[0].get('mass'), |
1858 | wf.get('mass'), |
1859 | wf.get('width'), |
1860 | wf.get('number')) |
1861 | self.add_wavefunction(key, call) |
1862 | |
1863 | - key = ((3,3,3,5),'') |
1864 | + key = ((3,3,3,5),('',)) |
1865 | call = lambda amp: \ |
1866 | "CALL VVVTXX(W(1,%d),W(1,%d),W(1,%d),W(1,%d),1d0,%s,AMP(%d))" % \ |
1867 | (amp.get('mothers')[0].get('number'), |
1868 | amp.get('mothers')[1].get('number'), |
1869 | amp.get('mothers')[2].get('number'), |
1870 | amp.get('mothers')[3].get('number'), |
1871 | - amp.get('coupling'), |
1872 | + amp.get('coupling')[0], |
1873 | amp.get('number')) |
1874 | self.add_amplitude(key, call) |
1875 | |
1876 | - key = ((3,3,5),'') |
1877 | + key = ((3,3,5),('',)) |
1878 | call = lambda amp: \ |
1879 | "CALL VVTXXX(W(1,%d),W(1,%d),W(1,%d),%s,%s,AMP(%d))" % \ |
1880 | (amp.get('mothers')[0].get('number'), |
1881 | amp.get('mothers')[1].get('number'), |
1882 | amp.get('mothers')[2].get('number'), |
1883 | - amp.get('coupling'), |
1884 | + amp.get('coupling')[0], |
1885 | amp.get('mothers')[0].get('mass'), |
1886 | amp.get('number')) |
1887 | self.add_amplitude(key, call) |
1888 | @@ -569,19 +570,18 @@ |
1889 | |
1890 | # If Lorentz structure is given, by default add this |
1891 | # to call name |
1892 | - addition = argument.get('lorentz') |
1893 | + lor_name = argument.get('lorentz')[0] |
1894 | |
1895 | # Take care of special case: WWWW or WWVV calls |
1896 | - if len(argument.get('lorentz')) > 3 and \ |
1897 | - argument.get('lorentz')[:2] == "WW": |
1898 | - if argument.get('lorentz')[:4] == "WWWW": |
1899 | + if len(lor_name) > 3 and lor_name[:2] == "WW": |
1900 | + if lor_name[:4] == "WWWW": |
1901 | mother_letters = "WWWW"[:len(mother_letters)] |
1902 | - if argument.get('lorentz')[:4] == "WWVV": |
1903 | + if lor_name[:4] == "WWVV": |
1904 | mother_letters = "W3W3"[:len(mother_letters)] |
1905 | - addition = argument.get('lorentz')[4:] |
1906 | + lor_name = lor_name[4:] |
1907 | |
1908 | call = call + mother_letters |
1909 | - call = call + addition |
1910 | + call = call + lor_name |
1911 | |
1912 | # Check if we need to append a charge conjugation flag |
1913 | if argument.needs_hermitian_conjugate(): |
1914 | @@ -641,7 +641,7 @@ |
1915 | get('number'), |
1916 | FortranHelasCallWriter.sorted_mothers(wf)[1].\ |
1917 | get('number'), |
1918 | - wf.get_with_flow('coupling'), |
1919 | + ','.join(wf.get_with_flow('coupling')), |
1920 | wf.get('mass'), |
1921 | wf.get('width'), |
1922 | wf.get('number')) |
1923 | @@ -653,7 +653,7 @@ |
1924 | get('number'), |
1925 | FortranHelasCallWriter.sorted_mothers(wf)[2].\ |
1926 | get('number'), |
1927 | - wf.get_with_flow('coupling'), |
1928 | + ','.join(wf.get_with_flow('coupling')), |
1929 | wf.get('mass'), |
1930 | wf.get('width'), |
1931 | wf.get('number')) |
1932 | @@ -668,7 +668,7 @@ |
1933 | FortranHelasCallWriter.sorted_mothers(amp)[2].\ |
1934 | get('number'), |
1935 | |
1936 | - amp.get('coupling'), |
1937 | + ','.join(amp.get('coupling')), |
1938 | amp.get('number')) |
1939 | else: |
1940 | call_function = lambda amp: call % \ |
1941 | @@ -680,7 +680,7 @@ |
1942 | get('number'), |
1943 | FortranHelasCallWriter.sorted_mothers(amp)[3].\ |
1944 | get('number'), |
1945 | - amp.get('coupling'), |
1946 | + ','.join(amp.get('coupling')), |
1947 | amp.get('number')) |
1948 | |
1949 | # Add the constructed function to wavefunction or amplitude dictionary |
1950 | @@ -926,12 +926,14 @@ |
1951 | outgoing = 0 |
1952 | |
1953 | # Check if we need to append a charge conjugation flag |
1954 | + l = [str(l) for l in argument.get('lorentz')] |
1955 | c_flag = '' |
1956 | if argument.needs_hermitian_conjugate(): |
1957 | c_flag = "".join(['C%d' % i for i in \ |
1958 | argument.get_conjugate_index()]) |
1959 | - |
1960 | - call = 'CALL %s%s_%s' % (argument.get('lorentz'), c_flag, outgoing) |
1961 | + routine_name = aloha_writers.combine_name( |
1962 | + '%s%s' % (l[0], c_flag), l[1:], outgoing) |
1963 | + call = 'CALL %s' % (routine_name) |
1964 | |
1965 | # Add the wave function |
1966 | call = call + '(' |
1967 | @@ -946,7 +948,7 @@ |
1968 | #CALL L_4_011(W(1,%d),W(1,%d),%s,%s, %s, W(1,%d)) |
1969 | call_function = lambda wf: call % \ |
1970 | (tuple([mother.get('number') for mother in wf.get('mothers')]) + \ |
1971 | - (wf.get_with_flow('coupling'), |
1972 | + (','.join(wf.get_with_flow('coupling')), |
1973 | wf.get('mass'), |
1974 | wf.get('width'), |
1975 | wf.get('number'))) |
1976 | @@ -956,7 +958,7 @@ |
1977 | call_function = lambda amp: call % \ |
1978 | (tuple([mother.get('number') |
1979 | for mother in amp.get('mothers')]) + \ |
1980 | - (amp.get('coupling'), |
1981 | + (','.join(amp.get('coupling')), |
1982 | amp.get('number'))) |
1983 | |
1984 | # Add the constructed function to wavefunction or amplitude dictionary |
1985 | @@ -1061,12 +1063,14 @@ |
1986 | outgoing = 0 |
1987 | |
1988 | # Check if we need to append a charge conjugation flag |
1989 | + l = [str(l) for l in argument.get('lorentz')] |
1990 | c_flag = '' |
1991 | if argument.needs_hermitian_conjugate(): |
1992 | c_flag = "".join(['C%d' % i for i in \ |
1993 | argument.get_conjugate_index()]) |
1994 | - |
1995 | - call = '%s%s_%s' % (argument.get('lorentz'), c_flag, outgoing) |
1996 | + routine_name = aloha_writers.combine_name( |
1997 | + '%s%s' % (l[0], c_flag), l[1:], outgoing) |
1998 | + call = '%s' % (routine_name) |
1999 | |
2000 | # Add the wave function |
2001 | call = call + '(' |
2002 | @@ -1081,8 +1085,8 @@ |
2003 | #CALL L_4_011(W(1,%d),W(1,%d),%s,%s, %s, W(1,%d)) |
2004 | call_function = lambda wf: call % \ |
2005 | (tuple([mother.get('number')-1 for mother in wf.get('mothers')]) + \ |
2006 | - (CPPUFOHelasCallWriter.format_coupling(\ |
2007 | - wf.get_with_flow('coupling')), |
2008 | + (','.join(CPPUFOHelasCallWriter.format_coupling(\ |
2009 | + wf.get_with_flow('coupling'))), |
2010 | wf.get('mass'), |
2011 | wf.get('width'), |
2012 | wf.get('number')-1)) |
2013 | @@ -1092,8 +1096,8 @@ |
2014 | call_function = lambda amp: call % \ |
2015 | (tuple([mother.get('number')-1 |
2016 | for mother in amp.get('mothers')]) + \ |
2017 | - (CPPUFOHelasCallWriter.format_coupling(\ |
2018 | - amp.get('coupling')), |
2019 | + (','.join(CPPUFOHelasCallWriter.format_coupling(\ |
2020 | + amp.get('coupling'))), |
2021 | amp.get('number')-1)) |
2022 | |
2023 | # Add the constructed function to wavefunction or amplitude dictionary |
2024 | @@ -1103,13 +1107,18 @@ |
2025 | self.add_amplitude(argument.get_call_key(), call_function) |
2026 | |
2027 | @staticmethod |
2028 | - def format_coupling(coupling): |
2029 | + def format_coupling(couplings): |
2030 | """Format the coupling so any minus signs are put in front""" |
2031 | |
2032 | - if coupling.startswith('-'): |
2033 | - return "-pars->" + coupling[1:] |
2034 | - else: |
2035 | - return "pars->" + coupling |
2036 | + output = [] |
2037 | + for coupling in couplings: |
2038 | + if coupling.startswith('-'): |
2039 | + output.append("-pars->" + coupling[1:]) |
2040 | + else: |
2041 | + output.append("pars->" + coupling) |
2042 | + |
2043 | + return output |
2044 | + |
2045 | |
2046 | #=============================================================================== |
2047 | # PythonUFOHelasCallWriter |
2048 | @@ -1229,16 +1238,20 @@ |
2049 | outgoing = 0 |
2050 | |
2051 | # Check if we need to append a charge conjugation flag |
2052 | + l = [str(l) for l in argument.get('lorentz')] |
2053 | c_flag = '' |
2054 | if argument.needs_hermitian_conjugate(): |
2055 | c_flag = "".join(['C%d' % i for i in \ |
2056 | argument.get_conjugate_index()]) |
2057 | + routine_name = aloha_writers.combine_name( |
2058 | + '%s%s' % (l[0], c_flag), l[1:], outgoing) |
2059 | + |
2060 | |
2061 | if isinstance(argument, helas_objects.HelasWavefunction): |
2062 | call = 'w[%d] = ' |
2063 | else: |
2064 | call = 'amp[%d] = ' |
2065 | - call += '%s%s_%s' % (argument.get('lorentz'), c_flag, outgoing) |
2066 | + call += '%s' % routine_name |
2067 | |
2068 | # Add the wave function |
2069 | call = call + '(' |
2070 | @@ -1255,7 +1268,7 @@ |
2071 | ((wf.get('number')-1,) + \ |
2072 | tuple([mother.get('number')-1 for mother in \ |
2073 | wf.get('mothers')]) + \ |
2074 | - (wf.get_with_flow('coupling'), |
2075 | + (','.join(wf.get_with_flow('coupling')), |
2076 | wf.get('mass'), |
2077 | wf.get('width'))) |
2078 | else: |
2079 | @@ -1265,7 +1278,7 @@ |
2080 | ((amp.get('number')-1,) + \ |
2081 | tuple([mother.get('number')-1 |
2082 | for mother in amp.get('mothers')]) + \ |
2083 | - (amp.get('coupling'),)) |
2084 | + (','.join(amp.get('coupling')),)) |
2085 | |
2086 | # Add the constructed function to wavefunction or amplitude dictionary |
2087 | if isinstance(argument, helas_objects.HelasWavefunction): |
2088 | |
2089 | === modified file 'madgraph/iolibs/template_files/matrix_madevent_v4.inc' |
2090 | --- madgraph/iolibs/template_files/matrix_madevent_v4.inc 2011-04-18 02:53:53 +0000 |
2091 | +++ madgraph/iolibs/template_files/matrix_madevent_v4.inc 2011-04-20 16:57:29 +0000 |
2092 | @@ -214,6 +214,8 @@ |
2093 | REAL*8 DENOM(NCOLOR), CF(NCOLOR,NCOLOR) |
2094 | COMPLEX*16 AMP(NGRAPHS), JAMP(NCOLOR) |
2095 | COMPLEX*16 W(18,NWAVEFUNCS) |
2096 | + COMPLEX*16 DUM0,DUM1 |
2097 | + DATA DUM0, DUM1/(0d0, 0d0), (1d0, 0d0)/ |
2098 | C |
2099 | C GLOBAL VARIABLES |
2100 | C |
2101 | |
2102 | === modified file 'madgraph/iolibs/template_files/matrix_standalone_v4.inc' |
2103 | --- madgraph/iolibs/template_files/matrix_standalone_v4.inc 2011-02-08 16:27:15 +0000 |
2104 | +++ madgraph/iolibs/template_files/matrix_standalone_v4.inc 2011-04-20 16:57:29 +0000 |
2105 | @@ -92,6 +92,8 @@ |
2106 | REAL*8 DENOM(NCOLOR), CF(NCOLOR,NCOLOR) |
2107 | COMPLEX*16 AMP(NGRAPHS), JAMP(NCOLOR) |
2108 | COMPLEX*16 W(18,NWAVEFUNCS) |
2109 | + COMPLEX*16 DUM0,DUM1 |
2110 | + DATA DUM0, DUM1/(0d0, 0d0), (1d0, 0d0)/ |
2111 | C |
2112 | C GLOBAL VARIABLES |
2113 | C |
2114 | |
2115 | === modified file 'tests/acceptance_tests/test_cmd.py' |
2116 | --- tests/acceptance_tests/test_cmd.py 2011-04-18 19:06:57 +0000 |
2117 | +++ tests/acceptance_tests/test_cmd.py 2011-04-20 16:57:29 +0000 |
2118 | @@ -913,7 +913,7 @@ |
2119 | self.do('import model sm') |
2120 | self.do('define p g u d u~ d~') |
2121 | self.do('define j g u d u~ d~') |
2122 | - self.do('generate p p > w+ j') |
2123 | + self.do('generate p p > w+ j @2') |
2124 | self.do('output pythia8 %s' % self.out_dir) |
2125 | # Check that the needed files are generated |
2126 | files = ['Processes_sm/Sigma_sm_gq_wpq.h', 'Processes_sm/Sigma_sm_gq_wpq.cc', |
2127 | @@ -933,7 +933,7 @@ |
2128 | shutil.rmdir(self.out_dir) |
2129 | |
2130 | self.do('import model sm') |
2131 | - self.do('generate e+ e- > e+ e-') |
2132 | + self.do('generate e+ e- > e+ e- @2') |
2133 | self.do('output standalone_cpp %s' % self.out_dir) |
2134 | |
2135 | # Check that all needed src files are generated |
2136 | @@ -955,21 +955,21 @@ |
2137 | subprocess.call(['make', 'check'], |
2138 | stdout=devnull, stderr=devnull, |
2139 | cwd=os.path.join(self.out_dir, 'SubProcesses', |
2140 | - 'P0_Sigma_sm_epem_epem')) |
2141 | + 'P2_Sigma_sm_epem_epem')) |
2142 | |
2143 | self.assertTrue(os.path.exists(os.path.join(self.out_dir, |
2144 | 'SubProcesses', |
2145 | - 'P0_Sigma_sm_epem_epem', |
2146 | + 'P2_Sigma_sm_epem_epem', |
2147 | 'check'))) |
2148 | |
2149 | # Check that the output of check is correct |
2150 | logfile = os.path.join(self.out_dir, 'SubProcesses', |
2151 | - 'P0_Sigma_sm_epem_epem', 'check.log') |
2152 | + 'P2_Sigma_sm_epem_epem', 'check.log') |
2153 | |
2154 | subprocess.call('./check', |
2155 | stdout=open(logfile, 'w'), stderr=devnull, |
2156 | cwd=os.path.join(self.out_dir, 'SubProcesses', |
2157 | - 'P0_Sigma_sm_epem_epem'), shell=True) |
2158 | + 'P2_Sigma_sm_epem_epem'), shell=True) |
2159 | |
2160 | log_output = open(logfile, 'r').read() |
2161 | me_re = re.compile('Matrix element\s*=\s*(?P<value>[\d\.e\+-]+)\s*GeV', |
2162 | |
2163 | === modified file 'tests/parallel_tests/me_comparator.py' |
2164 | --- tests/parallel_tests/me_comparator.py 2011-04-10 15:43:51 +0000 |
2165 | +++ tests/parallel_tests/me_comparator.py 2011-04-20 16:57:29 +0000 |
2166 | @@ -339,7 +339,7 @@ |
2167 | the specified model, the specified maximal coupling orders and a certain |
2168 | energy for incoming particles (for decay, incoming particle is at rest). |
2169 | """ |
2170 | - |
2171 | + self.res_list = [] # ensure that to be void, and avoid pointer problem |
2172 | self.proc_list = proc_list |
2173 | self.model = model |
2174 | self.orders = orders |
2175 | @@ -373,7 +373,8 @@ |
2176 | |
2177 | # Get the ME value |
2178 | for i, proc in enumerate(proc_list): |
2179 | - self.res_list.append(self.get_me_value(proc, i)) |
2180 | + value = self.get_me_value(proc, i) |
2181 | + self.res_list.append(value) |
2182 | |
2183 | return self.res_list |
2184 | |
2185 | |
2186 | === modified file 'tests/parallel_tests/sample_script.py' |
2187 | --- tests/parallel_tests/sample_script.py 2011-04-12 16:11:45 +0000 |
2188 | +++ tests/parallel_tests/sample_script.py 2011-04-20 16:57:29 +0000 |
2189 | @@ -46,6 +46,7 @@ |
2190 | logging.getLogger('tutorial').setLevel(logging.ERROR) |
2191 | |
2192 | logging.basicConfig(level=logging.INFO) |
2193 | +<<<<<<< TREE |
2194 | #my_proc_list = ['u u~ > g y $ g', 'u~ u > g y $ g ', 'y > u u~','Z > u u~'] |
2195 | #my_proc_list = ['t t > t t', 't t~ > t t~', 't t~ > z z', 't z > t z', 't~ t~ > t~ t~', 't~ z > t~ z', 'g g > y y', 'g y > g y', 'y y > g g', 'y y > z z', 'y y > a a', 'y z > t t~', 'y z > y z', 'a y > a y',' z z > t t~', 'z z > y y', 'a a > y y'] |
2196 | #my_proc_list = ['t t~ > t t~','e+ e- > e+ e-','w+ w- > w+ w-', 't t~ > t t~ / a z h g', 'y > t t~', 'y > t t~ g', 't t~ > t t~ / z h g','t t~ > t t~ / a h g','t t~ > t t~ / z a g', 't t~ > t t~ / h ', 't t~ > t t~ / z','t t~ > z > t t~', 'y t > t z', 't t~ > z > t t~'] |
2197 | @@ -74,6 +75,17 @@ |
2198 | #print len(my_proc_list) |
2199 | #print my_proc_list |
2200 | # |
2201 | +======= |
2202 | + |
2203 | + my_proc_list=['z z > z z','w+ w- > w+ w-','g g > g g', 'u u~ > g g g', 'u u~ > e+ e- z', 't t~ > g g' |
2204 | + 'e+ e- > e+ e- e+ e-', ' g g > t t~ g', 't t~ > h > t t~'] |
2205 | + #my_proc_list1 = me_comparator.create_proc_list(['u', 'u~','t','t~','g','y','z','a'], initial=1, |
2206 | + # final=2) |
2207 | + #my_proc_list = me_comparator.create_proc_list_enhanced( |
2208 | + # fermion, fermion, boson, |
2209 | + # initial=2, final_1=2, final_2 = 1) |
2210 | + |
2211 | +>>>>>>> MERGE-SOURCE |
2212 | #my_proc_list += me_comparator.create_proc_list(['w+','w-','z','a','x1+','x1-','n1'], initial=2, |
2213 | # final=3) |
2214 | #my_proc_list += me_comparator.create_proc_list(['g','u','u~','go','ul','ul~','ur','ur~'], initial=2, |
2215 | @@ -102,12 +114,17 @@ |
2216 | |
2217 | # Create and setup a comparator |
2218 | my_comp = me_comparator.MEComparator() |
2219 | - my_comp.set_me_runners(my_mg5_ufo, my_mg4) |
2220 | + my_comp.set_me_runners(my_mg5, my_mg5_ufo, my_mg5_cpp, my_mg4) |
2221 | |
2222 | # Run the actual comparison |
2223 | my_comp.run_comparison(my_proc_list, |
2224 | +<<<<<<< TREE |
2225 | model=['RS','RS'], |
2226 | orders={'QED':4, 'QCD':4, 'QTD':4}, energy=2000) |
2227 | +======= |
2228 | + model='sm', |
2229 | + orders={'QED':99, 'QCD':99, 'QTD':4}, energy=2000) |
2230 | +>>>>>>> MERGE-SOURCE |
2231 | |
2232 | # Do some cleanup |
2233 | #my_comp.cleanup() |
2234 | |
2235 | === modified file 'tests/unit_tests/core/test_helas_objects.py' |
2236 | --- tests/unit_tests/core/test_helas_objects.py 2010-12-19 03:57:07 +0000 |
2237 | +++ tests/unit_tests/core/test_helas_objects.py 2011-04-20 16:57:29 +0000 |
2238 | @@ -408,8 +408,8 @@ |
2239 | g, |
2240 | g]), |
2241 | 'color': [color.ColorString([color.f(0, 1, 2)]), |
2242 | - color.ColorString([color.f(0, 1, 2)]), |
2243 | - color.ColorString([color.f(0, 1, 2)])], |
2244 | + color.ColorString([color.f(1, 2, 0)]), |
2245 | + color.ColorString([color.f(2, 0, 1)])], |
2246 | 'lorentz':['gggg1', 'gggg2', 'gggg3'], |
2247 | 'couplings':{(0, 0):'GG',(1, 1):'GG',(2, 2):'GG'}, |
2248 | 'orders':{'QCD':2}})) |
2249 | @@ -1137,8 +1137,10 @@ |
2250 | matrix_element = helas_objects.HelasMatrixElement(\ |
2251 | myamplitude, |
2252 | 0) |
2253 | - |
2254 | - self.assertEqual(matrix_element.get('diagrams'), diagrams) |
2255 | + |
2256 | + self.assertEqual(matrix_element.get('diagrams')[0]['amplitudes'], amplitude1, |
2257 | + '%s != %s' %(matrix_element.get('diagrams')[0]['amplitudes'], amplitude1)) |
2258 | + #self.assertEqual(matrix_element.get('diagrams'), diagrams) |
2259 | |
2260 | def test_generate_helas_diagrams_ae_ae(self): |
2261 | """Testing the helas diagram generation a e- > a e- |
2262 | @@ -1888,9 +1890,9 @@ |
2263 | |
2264 | helas_writer = helas_call_writers.FortranUFOHelasCallWriter(mymodel) |
2265 | |
2266 | - self.assertEqual(len(me.get_all_amplitudes()), 8) |
2267 | + self.assertEqual(len(me.get_all_amplitudes()), 2) |
2268 | |
2269 | - self.assertEqual(len(me.get_all_wavefunctions()), 8) |
2270 | + self.assertEqual(len(me.get_all_wavefunctions()), 6) |
2271 | |
2272 | for i, amp in enumerate(me.get_all_amplitudes()): |
2273 | self.assertEqual(amp.get('number'), i + 1) |
2274 | |
2275 | === modified file 'tests/unit_tests/iolibs/test_export_cpp.py' |
2276 | --- tests/unit_tests/iolibs/test_export_cpp.py 2011-04-15 19:21:44 +0000 |
2277 | +++ tests/unit_tests/iolibs/test_export_cpp.py 2011-04-20 16:57:29 +0000 |
2278 | @@ -665,15 +665,30 @@ |
2279 | oxxxxx(p[perm[2]], mME[2], hel[2], +1, w[2]); |
2280 | ixxxxx(p[perm[3]], mME[3], hel[3], -1, w[3]); |
2281 | FFV1_3(w[0], w[1], pars->GC_10, pars->ZERO, pars->ZERO, w[4]); |
2282 | - FFV2_3(w[0], w[1], pars->GC_35, pars->MZ, pars->WZ, w[5]); |
2283 | - FFV5_3(w[0], w[1], pars->GC_47, pars->MZ, pars->WZ, w[6]); |
2284 | - FFV1_3(w[0], w[2], pars->GC_10, pars->ZERO, pars->ZERO, w[7]); |
2285 | - FFV2_3(w[0], w[2], pars->GC_35, pars->MZ, pars->WZ, w[8]); |
2286 | - FFV5_3(w[0], w[2], pars->GC_47, pars->MZ, pars->WZ, w[9]); |
2287 | - |
2288 | + FFV2_5_3(w[0], w[1], pars->GC_35, pars->GC_47, pars->MZ, pars->WZ, w[5]); |
2289 | + FFV1_3(w[0], w[2], pars->GC_10, pars->ZERO, pars->ZERO, w[6]); |
2290 | + FFV2_5_3(w[0], w[2], pars->GC_35, pars->GC_47, pars->MZ, pars->WZ, w[7]); |
2291 | + |
2292 | +<<<<<<< TREE |
2293 | +======= |
2294 | + |
2295 | +} |
2296 | +double Sigma_sm_qqx_qqx::matrix_uux_uux() |
2297 | +{ |
2298 | + int i, j; |
2299 | + // Local variables |
2300 | + const int ngraphs = 4; |
2301 | + const int ncolor = 2; |
2302 | + std::complex<double> ztemp; |
2303 | + std::complex<double> amp[ngraphs], jamp[ncolor]; |
2304 | + // The color matrix; |
2305 | + static const double denom[ncolor] = {1, 1}; |
2306 | + static const double cf[ncolor][ncolor] = {{9, 3}, {3, 9}}; |
2307 | +>>>>>>> MERGE-SOURCE |
2308 | // Calculate all amplitudes |
2309 | // Amplitude(s) for diagram number 0 |
2310 | FFV1_0(w[3], w[2], w[4], pars->GC_10, amp[0]); |
2311 | +<<<<<<< TREE |
2312 | FFV2_0(w[3], w[2], w[5], pars->GC_35, amp[1]); |
2313 | FFV5_0(w[3], w[2], w[5], pars->GC_47, amp[2]); |
2314 | FFV2_0(w[3], w[2], w[6], pars->GC_35, amp[3]); |
2315 | @@ -683,6 +698,14 @@ |
2316 | FFV5_0(w[3], w[1], w[8], pars->GC_47, amp[7]); |
2317 | FFV2_0(w[3], w[1], w[9], pars->GC_35, amp[8]); |
2318 | FFV5_0(w[3], w[1], w[9], pars->GC_47, amp[9]); |
2319 | +======= |
2320 | + // Amplitude(s) for diagram number 2 |
2321 | + FFV2_5_0(w[3], w[2], w[5], pars->GC_35, pars->GC_47, amp[1]); |
2322 | + // Amplitude(s) for diagram number 3 |
2323 | + FFV1_0(w[3], w[1], w[6], pars->GC_10, amp[2]); |
2324 | + // Amplitude(s) for diagram number 4 |
2325 | + FFV2_5_0(w[3], w[1], w[7], pars->GC_35, pars->GC_47, amp[3]); |
2326 | +>>>>>>> MERGE-SOURCE |
2327 | |
2328 | |
2329 | } |
2330 | @@ -699,10 +722,8 @@ |
2331 | static const double cf[ncolor][ncolor] = {{9, 3}, {3, 9}}; |
2332 | |
2333 | // Calculate color flows |
2334 | - jamp[0] = +1./6. * amp[0] - amp[1] - amp[2] - amp[3] - amp[4] + 1./2. * |
2335 | - amp[5]; |
2336 | - jamp[1] = -1./2. * amp[0] - 1./6. * amp[5] + amp[6] + amp[7] + amp[8] + |
2337 | - amp[9]; |
2338 | + jamp[0] = +1./6. * amp[0] - amp[1] + 1./2. * amp[2]; |
2339 | + jamp[1] = -1./2. * amp[0] - 1./6. * amp[2] + amp[3]; |
2340 | |
2341 | // Sum and square the color flows to get the matrix element |
2342 | double matrix = 0; |
2343 | @@ -1321,6 +1342,107 @@ |
2344 | print "cd /tmp; g++ -c -I $PATH_TO_PYTHIA8/include Sigma_sm_qqx_qqx.cc.cc" |
2345 | |
2346 | |
2347 | +<<<<<<< TREE |
2348 | +======= |
2349 | + def test_write_process_h_file(self): |
2350 | + """Test writing the .h Pythia file for a matrix element""" |
2351 | + |
2352 | + goal_string = \ |
2353 | +"""//========================================================================== |
2354 | +// This file has been automatically generated for Pythia 8 |
2355 | +// MadGraph 5 v. %(version)s, %(date)s |
2356 | +// By the MadGraph Development Team |
2357 | +// Please visit us at https://launchpad.net/madgraph5 |
2358 | +//========================================================================== |
2359 | + |
2360 | +#ifndef Pythia8_Sigma_sm_qqx_qqx_H |
2361 | +#define Pythia8_Sigma_sm_qqx_qqx_H |
2362 | + |
2363 | +#include <complex> |
2364 | + |
2365 | +#include "SigmaProcess.h" |
2366 | +#include "Parameters_sm.h" |
2367 | + |
2368 | +using namespace std; |
2369 | + |
2370 | +namespace Pythia8 |
2371 | +{ |
2372 | +//========================================================================== |
2373 | +// A class for calculating the matrix elements for |
2374 | +// Process: u u~ > u u~ |
2375 | +// Process: c c~ > c c~ |
2376 | +//-------------------------------------------------------------------------- |
2377 | + |
2378 | +class Sigma_sm_qqx_qqx : public Sigma2Process |
2379 | +{ |
2380 | + public: |
2381 | + |
2382 | + // Constructor. |
2383 | + Sigma_sm_qqx_qqx() {} |
2384 | + |
2385 | + // Initialize process. |
2386 | + virtual void initProc(); |
2387 | + |
2388 | + // Calculate flavour-independent parts of cross section. |
2389 | + virtual void sigmaKin(); |
2390 | + |
2391 | + // Evaluate sigmaHat(sHat). |
2392 | + virtual double sigmaHat(); |
2393 | + |
2394 | + // Select flavour, colour and anticolour. |
2395 | + virtual void setIdColAcol(); |
2396 | + |
2397 | + // Evaluate weight for decay angles. |
2398 | + virtual double weightDecay(Event& process, int iResBeg, int iResEnd); |
2399 | + |
2400 | + // Info on the subprocess. |
2401 | + virtual string name() const {return "q q~ > q q~ (sm)";} |
2402 | + |
2403 | + virtual int code() const {return 10000;} |
2404 | + |
2405 | + virtual string inFlux() const {return "qqbarSame";} |
2406 | + |
2407 | + virtual int resonanceA() const {return 23;} |
2408 | + // Tell Pythia that sigmaHat returns the ME^2 |
2409 | + virtual bool convertM2() const {return true;} |
2410 | + |
2411 | + private: |
2412 | + |
2413 | + // Private functions to calculate the matrix element for all subprocesses |
2414 | + // Calculate wavefunctions |
2415 | + void calculate_wavefunctions(const int perm[], const int hel[]); |
2416 | + static const int nwavefuncs = 8; |
2417 | + std::complex<double> w[nwavefuncs][18]; |
2418 | + double matrix_uux_uux(); |
2419 | + |
2420 | + // Constants for array limits |
2421 | + static const int nexternal = 4; |
2422 | + static const int nprocesses = 1; |
2423 | + |
2424 | + // Store the matrix element value from sigmaKin |
2425 | + double matrix_element[nprocesses]; |
2426 | + |
2427 | + // Color flows, used when selecting color |
2428 | + double * jamp2[nprocesses]; |
2429 | + |
2430 | + // Pointer to the model parameters |
2431 | + Parameters_sm * pars; |
2432 | + |
2433 | +}; |
2434 | + |
2435 | +} // end namespace Pythia |
2436 | + |
2437 | +#endif // Pythia8_Sigma_sm_qqx_qqx_H |
2438 | +""" % misc.get_pkg_info() |
2439 | + |
2440 | + self.pythia8_exporter.write_process_h_file(\ |
2441 | + writers.CPPWriter(self.give_pos('test.h'))) |
2442 | + |
2443 | + #print open(self.give_pos('test.h')).read() |
2444 | + |
2445 | + self.assertFileContains('test.h', goal_string) |
2446 | + |
2447 | +>>>>>>> MERGE-SOURCE |
2448 | #=============================================================================== |
2449 | # ExportUFOModelPythia8Test |
2450 | #=============================================================================== |
2451 | |
2452 | === modified file 'tests/unit_tests/iolibs/test_export_python.py' |
2453 | --- tests/unit_tests/iolibs/test_export_python.py 2011-03-24 15:44:58 +0000 |
2454 | +++ tests/unit_tests/iolibs/test_export_python.py 2011-04-20 16:57:29 +0000 |
2455 | @@ -299,9 +299,9 @@ |
2456 | # |
2457 | # Process parameters |
2458 | # |
2459 | - ngraphs = 10 |
2460 | + ngraphs = 4 |
2461 | nexternal = 4 |
2462 | - nwavefuncs = 10 |
2463 | + nwavefuncs = 8 |
2464 | ncolor = 2 |
2465 | ZERO = 0. |
2466 | # |
2467 | @@ -330,32 +330,24 @@ |
2468 | w[4] = FFV1_3(w[0],w[1],GC_10,ZERO, ZERO) |
2469 | # Amplitude(s) for diagram number 1 |
2470 | amp[0] = FFV1_0(w[3],w[2],w[4],GC_10) |
2471 | - w[5] = FFV2_3(w[0],w[1],GC_35,MZ, WZ) |
2472 | - w[6] = FFV5_3(w[0],w[1],GC_47,MZ, WZ) |
2473 | + w[5] = FFV2_5_3(w[0],w[1],GC_35,GC_47,MZ, WZ) |
2474 | # Amplitude(s) for diagram number 2 |
2475 | - amp[1] = FFV2_0(w[3],w[2],w[5],GC_35) |
2476 | - amp[2] = FFV5_0(w[3],w[2],w[5],GC_47) |
2477 | - amp[3] = FFV2_0(w[3],w[2],w[6],GC_35) |
2478 | - amp[4] = FFV5_0(w[3],w[2],w[6],GC_47) |
2479 | - w[7] = FFV1_3(w[0],w[2],GC_10,ZERO, ZERO) |
2480 | + amp[1] = FFV2_5_0(w[3],w[2],w[5],GC_35,GC_47) |
2481 | + w[6] = FFV1_3(w[0],w[2],GC_10,ZERO, ZERO) |
2482 | # Amplitude(s) for diagram number 3 |
2483 | - amp[5] = FFV1_0(w[3],w[1],w[7],GC_10) |
2484 | - w[8] = FFV2_3(w[0],w[2],GC_35,MZ, WZ) |
2485 | - w[9] = FFV5_3(w[0],w[2],GC_47,MZ, WZ) |
2486 | + amp[2] = FFV1_0(w[3],w[1],w[6],GC_10) |
2487 | + w[7] = FFV2_5_3(w[0],w[2],GC_35,GC_47,MZ, WZ) |
2488 | # Amplitude(s) for diagram number 4 |
2489 | - amp[6] = FFV2_0(w[3],w[1],w[8],GC_35) |
2490 | - amp[7] = FFV5_0(w[3],w[1],w[8],GC_47) |
2491 | - amp[8] = FFV2_0(w[3],w[1],w[9],GC_35) |
2492 | - amp[9] = FFV5_0(w[3],w[1],w[9],GC_47) |
2493 | + amp[3] = FFV2_5_0(w[3],w[1],w[7],GC_35,GC_47) |
2494 | |
2495 | jamp = [None] * ncolor |
2496 | - jamp[0] = +1./6.*amp[0]-amp[1]-amp[2]-amp[3]-amp[4]+1./2.*amp[5] |
2497 | - jamp[1] = -1./2.*amp[0]-1./6.*amp[5]+amp[6]+amp[7]+amp[8]+amp[9] |
2498 | + jamp[0] = +1./6.*amp[0]-amp[1]+1./2.*amp[2] |
2499 | + jamp[1] = -1./2.*amp[0]-1./6.*amp[2]+amp[3] |
2500 | |
2501 | self.amp2[0]+=abs(amp[0]*amp[0].conjugate()) |
2502 | - self.amp2[1]+=abs(amp[1]*amp[1].conjugate())+abs(amp[2]*amp[2].conjugate())+abs(amp[3]*amp[3].conjugate())+abs(amp[4]*amp[4].conjugate()) |
2503 | - self.amp2[2]+=abs(amp[5]*amp[5].conjugate()) |
2504 | - self.amp2[3]+=abs(amp[6]*amp[6].conjugate())+abs(amp[7]*amp[7].conjugate())+abs(amp[8]*amp[8].conjugate())+abs(amp[9]*amp[9].conjugate()) |
2505 | + self.amp2[1]+=abs(amp[1]*amp[1].conjugate()) |
2506 | + self.amp2[2]+=abs(amp[2]*amp[2].conjugate()) |
2507 | + self.amp2[3]+=abs(amp[3]*amp[3].conjugate()) |
2508 | |
2509 | matrix = 0. |
2510 | for i in range(ncolor): |
2511 | @@ -373,9 +365,8 @@ |
2512 | matrix_methods = exporter.get_python_matrix_methods()["0_uux_uux"].\ |
2513 | split('\n') |
2514 | |
2515 | - for iline in range(len(goal_method)): |
2516 | - self.assertEqual(matrix_methods[iline], |
2517 | - goal_method[iline]) |
2518 | + |
2519 | + self.assertEqual(matrix_methods, goal_method) |
2520 | |
2521 | |
2522 | def test_run_python_matrix_element(self): |
2523 | |
2524 | === modified file 'tests/unit_tests/iolibs/test_export_v4.py' |
2525 | --- tests/unit_tests/iolibs/test_export_v4.py 2011-04-18 02:53:53 +0000 |
2526 | +++ tests/unit_tests/iolibs/test_export_v4.py 2011-04-20 16:57:29 +0000 |
2527 | @@ -276,6 +276,8 @@ |
2528 | REAL*8 DENOM(NCOLOR), CF(NCOLOR,NCOLOR) |
2529 | COMPLEX*16 AMP(NGRAPHS), JAMP(NCOLOR) |
2530 | COMPLEX*16 W(18,NWAVEFUNCS) |
2531 | + COMPLEX*16 DUM0,DUM1 |
2532 | + DATA DUM0, DUM1/(0D0, 0D0), (1D0, 0D0)/ |
2533 | C |
2534 | C GLOBAL VARIABLES |
2535 | C |
2536 | @@ -599,13 +601,21 @@ |
2537 | amp2_lines = \ |
2538 | exporter.get_amp2_lines(matrix_elements[0], |
2539 | subprocess_group.get('diagram_maps')[0]) |
2540 | + |
2541 | self.assertEqual(amp2_lines, |
2542 | +<<<<<<< TREE |
2543 | ['AMP2(1)=AMP2(1)+AMP(1)*dconjg(AMP(1))', |
2544 | 'AMP2(2)=AMP2(2)+AMP(2)*dconjg(AMP(2))', |
2545 | 'AMP2(3)=AMP2(3)+AMP(3)*dconjg(AMP(3))+AMP(4)*dconjg(AMP(4))+AMP(5)*dconjg(AMP(5))+AMP(6)*dconjg(AMP(6))', |
2546 | 'AMP2(4)=AMP2(4)+AMP(7)*dconjg(AMP(7))', |
2547 | 'AMP2(5)=AMP2(5)+AMP(8)*dconjg(AMP(8))', |
2548 | 'AMP2(6)=AMP2(6)+AMP(9)*dconjg(AMP(9))+AMP(10)*dconjg(AMP(10))+AMP(11)*dconjg(AMP(11))+AMP(12)*dconjg(AMP(12))']) |
2549 | +======= |
2550 | + ['AMP2(1)=AMP2(1)+AMP(1)*dconjg(AMP(1))+AMP(2)*dconjg(AMP(2))', |
2551 | + 'AMP2(3)=AMP2(3)+AMP(3)*dconjg(AMP(3))', |
2552 | + 'AMP2(4)=AMP2(4)+AMP(4)*dconjg(AMP(4))+AMP(5)*dconjg(AMP(5))', |
2553 | + 'AMP2(6)=AMP2(6)+AMP(6)*dconjg(AMP(6))']) |
2554 | +>>>>>>> MERGE-SOURCE |
2555 | |
2556 | # Test configs.inc |
2557 | |
2558 | @@ -1758,14 +1768,14 @@ |
2559 | #print '\n'.join(amp2_lines) |
2560 | |
2561 | self.assertEqual('\n'.join(amp2_lines), |
2562 | -"""AMP2(5)=AMP2(5)+AMP(9)*dconjg(AMP(9)) |
2563 | -AMP2(6)=AMP2(6)+AMP(10)*dconjg(AMP(10)) |
2564 | -AMP2(7)=AMP2(7)+AMP(11)*dconjg(AMP(11)) |
2565 | -AMP2(8)=AMP2(8)+AMP(12)*dconjg(AMP(12)) |
2566 | -AMP2(9)=AMP2(9)+AMP(13)*dconjg(AMP(13)) |
2567 | -AMP2(10)=AMP2(10)+AMP(14)*dconjg(AMP(14)) |
2568 | -AMP2(11)=AMP2(11)+AMP(15)*dconjg(AMP(15)) |
2569 | -AMP2(12)=AMP2(12)+AMP(16)*dconjg(AMP(16))""") |
2570 | +"""AMP2(5)=AMP2(5)+AMP(5)*dconjg(AMP(5)) |
2571 | +AMP2(6)=AMP2(6)+AMP(6)*dconjg(AMP(6)) |
2572 | +AMP2(7)=AMP2(7)+AMP(7)*dconjg(AMP(7)) |
2573 | +AMP2(8)=AMP2(8)+AMP(8)*dconjg(AMP(8)) |
2574 | +AMP2(9)=AMP2(9)+AMP(9)*dconjg(AMP(9)) |
2575 | +AMP2(10)=AMP2(10)+AMP(10)*dconjg(AMP(10)) |
2576 | +AMP2(11)=AMP2(11)+AMP(11)*dconjg(AMP(11)) |
2577 | +AMP2(12)=AMP2(12)+AMP(12)*dconjg(AMP(12))""") |
2578 | |
2579 | # Test configs.inc |
2580 | |
2581 | @@ -3913,13 +3923,13 @@ |
2582 | |
2583 | # Test get_used_lorentz |
2584 | # Wavefunctions |
2585 | - goal_lorentz_list = [('', (), 1), ('', (), 2), ('', (), 3), |
2586 | - ('', (1,), 2),('', (), 3), ('', (1,), 1), |
2587 | - ('', (), 2), ('', (), 3),('', (1,), 1), |
2588 | - ('', (), 1), ('', (), 3),('', (1,), 2), |
2589 | - ('', (), 3), ('', (), 3)] |
2590 | + goal_lorentz_list = [(('',), (), 1), (('',), (), 2), (('',), (), 3), |
2591 | + (('',), (1,), 2),(('',), (), 3), (('',), (1,), 1), |
2592 | + (('',), (), 2), (('',), (), 3),(('',), (1,), 1), |
2593 | + (('',), (), 1), (('',), (), 3),(('',), (1,), 2), |
2594 | + (('',), (), 3), (('',), (), 3)] |
2595 | # Amplitudes |
2596 | - goal_lorentz_list += [('', (), 0)] * 8 |
2597 | + goal_lorentz_list += [(('',), (), 0)] * 8 |
2598 | self.assertEqual(matrix_element.get_used_lorentz(), |
2599 | goal_lorentz_list) |
2600 | |
2601 | @@ -4741,34 +4751,21 @@ |
2602 | |
2603 | matrix_element = helas_objects.HelasMatrixElement(myamplitude, gen_color=False) |
2604 | |
2605 | - myfortranmodel = helas_call_writers.FortranHelasCallWriter(mybasemodel) |
2606 | - self.assertEqual("\n".join(myfortranmodel.\ |
2607 | - get_matrix_element_calls(matrix_element)), |
2608 | + myfortranmodel = helas_call_writers.FortranUFOHelasCallWriter(mybasemodel) |
2609 | + self.assertEqual(myfortranmodel.get_matrix_element_calls(matrix_element), |
2610 | """CALL VXXXXX(P(0,1),zero,NHEL(1),-1*IC(1),W(1,1)) |
2611 | CALL VXXXXX(P(0,2),zero,NHEL(2),-1*IC(2),W(1,2)) |
2612 | CALL VXXXXX(P(0,3),zero,NHEL(3),+1*IC(3),W(1,3)) |
2613 | CALL VXXXXX(P(0,4),zero,NHEL(4),+1*IC(4),W(1,4)) |
2614 | -CALL JVVL1X(W(1,1),W(1,2),G1,zero,zero,W(1,5)) |
2615 | -CALL JVVL2X(W(1,1),W(1,2),G2,zero,zero,W(1,6)) |
2616 | +CALL L1__L2_1(W(1,1),W(1,2),G1,G2,zero, zero, W(1,5)) |
2617 | # Amplitude(s) for diagram number 1 |
2618 | -CALL VVVL1X(W(1,3),W(1,4),W(1,5),G1,AMP(1)) |
2619 | -CALL VVVL2X(W(1,3),W(1,4),W(1,5),G2,AMP(2)) |
2620 | -CALL VVVL1X(W(1,3),W(1,4),W(1,6),G1,AMP(3)) |
2621 | -CALL VVVL2X(W(1,3),W(1,4),W(1,6),G2,AMP(4)) |
2622 | -CALL JVVL1X(W(1,1),W(1,3),G1,zero,zero,W(1,7)) |
2623 | -CALL JVVL2X(W(1,1),W(1,3),G2,zero,zero,W(1,8)) |
2624 | +CALL L1__L2_0(W(1,3),W(1,4),W(1,5),G1,G2,AMP(1)) |
2625 | +CALL L1__L2_1(W(1,1),W(1,3),G1,G2,zero, zero, W(1,6)) |
2626 | # Amplitude(s) for diagram number 2 |
2627 | -CALL VVVL1X(W(1,2),W(1,4),W(1,7),G1,AMP(5)) |
2628 | -CALL VVVL2X(W(1,2),W(1,4),W(1,7),G2,AMP(6)) |
2629 | -CALL VVVL1X(W(1,2),W(1,4),W(1,8),G1,AMP(7)) |
2630 | -CALL VVVL2X(W(1,2),W(1,4),W(1,8),G2,AMP(8)) |
2631 | -CALL JVVL1X(W(1,1),W(1,4),G1,zero,zero,W(1,9)) |
2632 | -CALL JVVL2X(W(1,1),W(1,4),G2,zero,zero,W(1,10)) |
2633 | +CALL L1__L2_0(W(1,2),W(1,4),W(1,6),G1,G2,AMP(2)) |
2634 | +CALL L1__L2_1(W(1,1),W(1,4),G1,G2,zero, zero, W(1,7)) |
2635 | # Amplitude(s) for diagram number 3 |
2636 | -CALL VVVL1X(W(1,2),W(1,3),W(1,9),G1,AMP(9)) |
2637 | -CALL VVVL2X(W(1,2),W(1,3),W(1,9),G2,AMP(10)) |
2638 | -CALL VVVL1X(W(1,2),W(1,3),W(1,10),G1,AMP(11)) |
2639 | -CALL VVVL2X(W(1,2),W(1,3),W(1,10),G2,AMP(12))""") |
2640 | +CALL L1__L2_0(W(1,2),W(1,3),W(1,7),G1,G2,AMP(3))""".split('\n')) |
2641 | |
2642 | exporter = export_v4.ProcessExporterFortranME() |
2643 | |
2644 | @@ -4776,9 +4773,9 @@ |
2645 | amp2_lines = \ |
2646 | exporter.get_amp2_lines(matrix_element) |
2647 | self.assertEqual(amp2_lines, |
2648 | - ['AMP2(1)=AMP2(1)+AMP(1)*dconjg(AMP(1))+AMP(2)*dconjg(AMP(2))+AMP(3)*dconjg(AMP(3))+AMP(4)*dconjg(AMP(4))', |
2649 | - 'AMP2(2)=AMP2(2)+AMP(5)*dconjg(AMP(5))+AMP(6)*dconjg(AMP(6))+AMP(7)*dconjg(AMP(7))+AMP(8)*dconjg(AMP(8))', |
2650 | - 'AMP2(3)=AMP2(3)+AMP(9)*dconjg(AMP(9))+AMP(10)*dconjg(AMP(10))+AMP(11)*dconjg(AMP(11))+AMP(12)*dconjg(AMP(12))']) |
2651 | + ['AMP2(1)=AMP2(1)+AMP(1)*dconjg(AMP(1))', |
2652 | + 'AMP2(2)=AMP2(2)+AMP(2)*dconjg(AMP(2))', |
2653 | + 'AMP2(3)=AMP2(3)+AMP(3)*dconjg(AMP(3))']) |
2654 | |
2655 | # Test configs file |
2656 | writer = writers.FortranWriter(self.give_pos('test')) |
2657 | @@ -4963,45 +4960,23 @@ |
2658 | CALL IXXXXX(P(0,4),Mx1p,NHEL(4),-1*IC(4),W(1,4)) |
2659 | CALL OXXXXX(P(0,5),Mx1p,NHEL(5),+1*IC(5),W(1,5)) |
2660 | CALL VVV1_2(W(1,1),W(1,3),GC_214,MW, WW, W(1,6)) |
2661 | -CALL FFV2C1_2(W(1,4),W(1,2),GC_422,Mneu1, Wneu1, W(1,7)) |
2662 | -CALL FFV3C1_2(W(1,4),W(1,2),GC_628,Mneu1, Wneu1, W(1,8)) |
2663 | +CALL FFV2C1_3_2(W(1,4),W(1,2),GC_422,GC_628,Mneu1, Wneu1, W(1,7)) |
2664 | # Amplitude(s) for diagram number 1 |
2665 | -CALL FFV2_0(W(1,7),W(1,5),W(1,6),GC_422,AMP(1)) |
2666 | -CALL FFV3_0(W(1,7),W(1,5),W(1,6),GC_628,AMP(2)) |
2667 | -CALL FFV2_0(W(1,8),W(1,5),W(1,6),GC_422,AMP(3)) |
2668 | -CALL FFV3_0(W(1,8),W(1,5),W(1,6),GC_628,AMP(4)) |
2669 | -CALL FFV2_1(W(1,5),W(1,2),GC_422,Mneu1, Wneu1, W(1,9)) |
2670 | -CALL FFV3_1(W(1,5),W(1,2),GC_628,Mneu1, Wneu1, W(1,10)) |
2671 | +CALL FFV2_3_0(W(1,7),W(1,5),W(1,6),GC_422,GC_628,AMP(1)) |
2672 | +CALL FFV2_3_1(W(1,5),W(1,2),GC_422,GC_628,Mneu1, Wneu1, W(1,8)) |
2673 | # Amplitude(s) for diagram number 2 |
2674 | -CALL FFV2C1_0(W(1,4),W(1,9),W(1,6),GC_422,AMP(5)) |
2675 | -CALL FFV3C1_0(W(1,4),W(1,9),W(1,6),GC_628,AMP(6)) |
2676 | -CALL FFV2C1_0(W(1,4),W(1,10),W(1,6),GC_422,AMP(7)) |
2677 | -CALL FFV3C1_0(W(1,4),W(1,10),W(1,6),GC_628,AMP(8)) |
2678 | -CALL FFV2C1_2(W(1,4),W(1,1),GC_422,Mneu1, Wneu1, W(1,11)) |
2679 | -CALL FFV3C1_2(W(1,4),W(1,1),GC_628,Mneu1, Wneu1, W(1,12)) |
2680 | -CALL VVV1_2(W(1,2),W(1,3),GC_214,MW, WW, W(1,13)) |
2681 | +CALL FFV2C1_3_0(W(1,4),W(1,8),W(1,6),GC_422,GC_628,AMP(2)) |
2682 | +CALL FFV2C1_3_2(W(1,4),W(1,1),GC_422,GC_628,Mneu1, Wneu1, W(1,9)) |
2683 | +CALL VVV1_2(W(1,2),W(1,3),GC_214,MW, WW, W(1,10)) |
2684 | # Amplitude(s) for diagram number 3 |
2685 | -CALL FFV2_0(W(1,11),W(1,5),W(1,13),GC_422,AMP(9)) |
2686 | -CALL FFV3_0(W(1,11),W(1,5),W(1,13),GC_628,AMP(10)) |
2687 | -CALL FFV2_0(W(1,12),W(1,5),W(1,13),GC_422,AMP(11)) |
2688 | -CALL FFV3_0(W(1,12),W(1,5),W(1,13),GC_628,AMP(12)) |
2689 | +CALL FFV2_3_0(W(1,9),W(1,5),W(1,10),GC_422,GC_628,AMP(3)) |
2690 | # Amplitude(s) for diagram number 4 |
2691 | -CALL FFV5_0(W(1,11),W(1,9),W(1,3),GC_418,AMP(13)) |
2692 | -CALL FFV5_0(W(1,11),W(1,10),W(1,3),GC_418,AMP(14)) |
2693 | -CALL FFV5_0(W(1,12),W(1,9),W(1,3),GC_418,AMP(15)) |
2694 | -CALL FFV5_0(W(1,12),W(1,10),W(1,3),GC_418,AMP(16)) |
2695 | -CALL FFV2_1(W(1,5),W(1,1),GC_422,Mneu1, Wneu1, W(1,14)) |
2696 | -CALL FFV3_1(W(1,5),W(1,1),GC_628,Mneu1, Wneu1, W(1,15)) |
2697 | +CALL FFV5_0(W(1,9),W(1,8),W(1,3),GC_418,AMP(4)) |
2698 | +CALL FFV2_3_1(W(1,5),W(1,1),GC_422,GC_628,Mneu1, Wneu1, W(1,11)) |
2699 | # Amplitude(s) for diagram number 5 |
2700 | -CALL FFV2C1_0(W(1,4),W(1,14),W(1,13),GC_422,AMP(17)) |
2701 | -CALL FFV3C1_0(W(1,4),W(1,14),W(1,13),GC_628,AMP(18)) |
2702 | -CALL FFV2C1_0(W(1,4),W(1,15),W(1,13),GC_422,AMP(19)) |
2703 | -CALL FFV3C1_0(W(1,4),W(1,15),W(1,13),GC_628,AMP(20)) |
2704 | +CALL FFV2C1_3_0(W(1,4),W(1,11),W(1,10),GC_422,GC_628,AMP(5)) |
2705 | # Amplitude(s) for diagram number 6 |
2706 | -CALL FFV5_0(W(1,7),W(1,14),W(1,3),GC_418,AMP(21)) |
2707 | -CALL FFV5_0(W(1,8),W(1,14),W(1,3),GC_418,AMP(22)) |
2708 | -CALL FFV5_0(W(1,7),W(1,15),W(1,3),GC_418,AMP(23)) |
2709 | -CALL FFV5_0(W(1,8),W(1,15),W(1,3),GC_418,AMP(24))""".split('\n') |
2710 | +CALL FFV5_0(W(1,7),W(1,11),W(1,3),GC_418,AMP(6))""".split('\n') |
2711 | |
2712 | for i in range(len(goal)): |
2713 | self.assertEqual(result[i], goal[i]) |
2714 | @@ -5012,12 +4987,12 @@ |
2715 | amp2_lines = \ |
2716 | exporter.get_amp2_lines(matrix_element) |
2717 | self.assertEqual(amp2_lines, |
2718 | - ['AMP2(1)=AMP2(1)+AMP(1)*dconjg(AMP(1))+AMP(2)*dconjg(AMP(2))+AMP(3)*dconjg(AMP(3))+AMP(4)*dconjg(AMP(4))', |
2719 | - 'AMP2(2)=AMP2(2)+AMP(5)*dconjg(AMP(5))+AMP(6)*dconjg(AMP(6))+AMP(7)*dconjg(AMP(7))+AMP(8)*dconjg(AMP(8))', |
2720 | - 'AMP2(3)=AMP2(3)+AMP(9)*dconjg(AMP(9))+AMP(10)*dconjg(AMP(10))+AMP(11)*dconjg(AMP(11))+AMP(12)*dconjg(AMP(12))', |
2721 | - 'AMP2(4)=AMP2(4)+AMP(13)*dconjg(AMP(13))+AMP(14)*dconjg(AMP(14))+AMP(15)*dconjg(AMP(15))+AMP(16)*dconjg(AMP(16))', |
2722 | - 'AMP2(5)=AMP2(5)+AMP(17)*dconjg(AMP(17))+AMP(18)*dconjg(AMP(18))+AMP(19)*dconjg(AMP(19))+AMP(20)*dconjg(AMP(20))', |
2723 | - 'AMP2(6)=AMP2(6)+AMP(21)*dconjg(AMP(21))+AMP(22)*dconjg(AMP(22))+AMP(23)*dconjg(AMP(23))+AMP(24)*dconjg(AMP(24))']) |
2724 | + ['AMP2(1)=AMP2(1)+AMP(1)*dconjg(AMP(1))', |
2725 | + 'AMP2(2)=AMP2(2)+AMP(2)*dconjg(AMP(2))', |
2726 | + 'AMP2(3)=AMP2(3)+AMP(3)*dconjg(AMP(3))', |
2727 | + 'AMP2(4)=AMP2(4)+AMP(4)*dconjg(AMP(4))', |
2728 | + 'AMP2(5)=AMP2(5)+AMP(5)*dconjg(AMP(5))', |
2729 | + 'AMP2(6)=AMP2(6)+AMP(6)*dconjg(AMP(6))']) |
2730 | |
2731 | def test_four_fermion_vertex_normal_fermion_flow(self): |
2732 | """Testing process u u > t t g with fermion flow (u~t)(u~t) |
2733 | @@ -5550,24 +5525,21 @@ |
2734 | |
2735 | result = helas_call_writers.FortranUFOHelasCallWriter(mybasemodel).\ |
2736 | get_matrix_element_calls(matrix_element.get('core_processes')[0]) |
2737 | - self.assertEqual("\n".join(result), |
2738 | + self.assertEqual(result, |
2739 | """CALL OXXXXX(P(0,1),zero,NHEL(1),-1*IC(1),W(1,1)) |
2740 | CALL IXXXXX(P(0,2),MT,NHEL(2),+1*IC(2),W(1,2)) |
2741 | CALL VXXXXX(P(0,3),Mwp,NHEL(3),+1*IC(3),W(1,3)) |
2742 | # Amplitude(s) for diagram number 1 |
2743 | -CALL FFS3_0(W(1,2),W(1,1),W(1,3),GC_108,AMP(1)) |
2744 | -CALL FFS4_0(W(1,2),W(1,1),W(1,3),GC_111,AMP(2))""") |
2745 | +CALL FFS3_4_0(W(1,2),W(1,1),W(1,3),GC_108,GC_111,AMP(1))""".split('\n')) |
2746 | result = helas_call_writers.FortranUFOHelasCallWriter(mybasemodel).\ |
2747 | get_matrix_element_calls(matrix_element.get('decay_chains')[0].get('core_processes')[0]) |
2748 | - self.assertEqual("\n".join(result), |
2749 | + self.assertEqual(result, |
2750 | """CALL VXXXXX(P(0,1),Mwp,NHEL(1),-1*IC(1),W(1,1)) |
2751 | CALL IXXXXX(P(0,2),zero,NHEL(2),-1*IC(2),W(1,2)) |
2752 | CALL OXXXXX(P(0,3),MT,NHEL(3),+1*IC(3),W(1,3)) |
2753 | -CALL FFS3_3(W(1,2),W(1,3),GC_108,Mwp, Wwp, W(1,4)) |
2754 | -CALL FFS4_3(W(1,2),W(1,3),GC_111,Mwp, Wwp, W(1,5)) |
2755 | +CALL FFS3_4_3(W(1,2),W(1,3),GC_108,GC_111,Mwp, Wwp, W(1,4)) |
2756 | # Amplitude(s) for diagram number 1 |
2757 | -# |
2758 | -#""") |
2759 | +#""".split('\n')) |
2760 | |
2761 | matrix_elements = matrix_element.combine_decay_chain_processes() |
2762 | |
2763 | @@ -5580,13 +5552,9 @@ |
2764 | CALL IXXXXX(P(0,2),MT,NHEL(2),+1*IC(2),W(1,2)) |
2765 | CALL IXXXXX(P(0,3),zero,NHEL(3),-1*IC(3),W(1,3)) |
2766 | CALL OXXXXX(P(0,4),MT,NHEL(4),+1*IC(4),W(1,4)) |
2767 | -CALL FFS3_3(W(1,3),W(1,4),GC_108,Mwp, Wwp, W(1,5)) |
2768 | -CALL FFS4_3(W(1,3),W(1,4),GC_111,Mwp, Wwp, W(1,6)) |
2769 | +CALL FFS3_4_3(W(1,3),W(1,4),GC_108,GC_111,Mwp, Wwp, W(1,5)) |
2770 | # Amplitude(s) for diagram number 1 |
2771 | -CALL FFS3_0(W(1,2),W(1,1),W(1,5),GC_108,AMP(1)) |
2772 | -CALL FFS3_0(W(1,2),W(1,1),W(1,6),GC_108,AMP(2)) |
2773 | -CALL FFS4_0(W(1,2),W(1,1),W(1,5),GC_111,AMP(3)) |
2774 | -CALL FFS4_0(W(1,2),W(1,1),W(1,6),GC_111,AMP(4))""".split('\n') |
2775 | +CALL FFS3_4_0(W(1,2),W(1,1),W(1,5),GC_108,GC_111,AMP(1))""".split('\n') |
2776 | |
2777 | for i in range(len(goal)): |
2778 | self.assertEqual(result[i], goal[i]) |
2779 | @@ -5705,24 +5673,21 @@ |
2780 | |
2781 | result = helas_call_writers.FortranUFOHelasCallWriter(mybasemodel).\ |
2782 | get_matrix_element_calls(matrix_element.get('core_processes')[0]) |
2783 | - self.assertEqual("\n".join(result), |
2784 | + self.assertEqual(result, |
2785 | """CALL OXXXXX(P(0,1),zero,NHEL(1),-1*IC(1),W(1,1)) |
2786 | CALL IXXXXX(P(0,2),MT,NHEL(2),+1*IC(2),W(1,2)) |
2787 | CALL SXXXXX(P(0,3),+1*IC(3),W(1,3)) |
2788 | # Amplitude(s) for diagram number 1 |
2789 | -CALL FFS3C1_0(W(1,2),W(1,1),W(1,3),GC_108,AMP(1)) |
2790 | -CALL FFS4C1_0(W(1,2),W(1,1),W(1,3),GC_111,AMP(2))""") |
2791 | +CALL FFS3C1_4_0(W(1,2),W(1,1),W(1,3),GC_108,GC_111,AMP(1))""".split('\n')) |
2792 | result = helas_call_writers.FortranUFOHelasCallWriter(mybasemodel).\ |
2793 | get_matrix_element_calls(matrix_element.get('decay_chains')[0].get('core_processes')[0]) |
2794 | - self.assertEqual("\n".join(result), |
2795 | + self.assertEqual(result, |
2796 | """CALL SXXXXX(P(0,1),-1*IC(1),W(1,1)) |
2797 | CALL OXXXXX(P(0,2),zero,NHEL(2),+1*IC(2),W(1,2)) |
2798 | CALL IXXXXX(P(0,3),MT,NHEL(3),-1*IC(3),W(1,3)) |
2799 | -CALL FFS3C1_3(W(1,3),W(1,2),GC_108,Msix1, Wsix1, W(1,4)) |
2800 | -CALL FFS4C1_3(W(1,3),W(1,2),GC_111,Msix1, Wsix1, W(1,5)) |
2801 | +CALL FFS3C1_4_3(W(1,3),W(1,2),GC_108,GC_111,Msix1, Wsix1, W(1,4)) |
2802 | # Amplitude(s) for diagram number 1 |
2803 | -# |
2804 | -#""") |
2805 | +#""".split('\n')) |
2806 | |
2807 | matrix_elements = matrix_element.combine_decay_chain_processes() |
2808 | |
2809 | @@ -5735,16 +5700,12 @@ |
2810 | CALL IXXXXX(P(0,2),MT,NHEL(2),+1*IC(2),W(1,2)) |
2811 | CALL OXXXXX(P(0,3),zero,NHEL(3),+1*IC(3),W(1,3)) |
2812 | CALL IXXXXX(P(0,4),MT,NHEL(4),-1*IC(4),W(1,4)) |
2813 | -CALL FFS3C1_3(W(1,4),W(1,3),GC_108,Msix1, Wsix1, W(1,5)) |
2814 | -CALL FFS4C1_3(W(1,4),W(1,3),GC_111,Msix1, Wsix1, W(1,6)) |
2815 | +CALL FFS3C1_4_3(W(1,4),W(1,3),GC_108,GC_111,Msix1, Wsix1, W(1,5)) |
2816 | # Amplitude(s) for diagram number 1 |
2817 | -CALL FFS3C1_0(W(1,2),W(1,1),W(1,5),GC_108,AMP(1)) |
2818 | -CALL FFS3C1_0(W(1,2),W(1,1),W(1,6),GC_108,AMP(2)) |
2819 | -CALL FFS4C1_0(W(1,2),W(1,1),W(1,5),GC_111,AMP(3)) |
2820 | -CALL FFS4C1_0(W(1,2),W(1,1),W(1,6),GC_111,AMP(4))""".split('\n') |
2821 | +CALL FFS3C1_4_0(W(1,2),W(1,1),W(1,5),GC_108,GC_111,AMP(1))""".split('\n') |
2822 | |
2823 | - for i in range(len(goal)): |
2824 | - self.assertEqual(result[i], goal[i]) |
2825 | + |
2826 | + self.assertEqual(result, goal) |
2827 | |
2828 | def test_matrix_multistage_decay_chain_process(self): |
2829 | """Test matrix.f for multistage decay chain |
2830 | @@ -6033,8 +5994,8 @@ |
2831 | g, |
2832 | g]), |
2833 | 'color': [color.ColorString([color.f(0, 1, 2)]), |
2834 | - color.ColorString([color.f(0, 1, 2)]), |
2835 | - color.ColorString([color.f(0, 1, 2)])], |
2836 | + color.ColorString([color.f(2, 1, 0)]), |
2837 | + color.ColorString([color.f(1, 0, 2)])], |
2838 | 'lorentz':['gggg1', 'gggg2', 'gggg3'], |
2839 | 'couplings':{(0, 0):'GG', (1, 1):'GG', (2, 2):'GG'}, |
2840 | 'orders':{'QCD':2}})) |
2841 | @@ -7760,7 +7721,7 @@ |
2842 | gen_color=True) |
2843 | |
2844 | self.assertEqual(sum([len(diagram.get('amplitudes')) for diagram in \ |
2845 | - me.get('diagrams')]), 8) |
2846 | + me.get('diagrams')]), 2) |
2847 | |
2848 | for i, amp in enumerate(me.get_all_amplitudes()): |
2849 | self.assertEqual(amp.get('number'), i + 1) |
2850 | @@ -7770,8 +7731,8 @@ |
2851 | exporter = export_v4.ProcessExporterFortranME() |
2852 | |
2853 | self.assertEqual(exporter.get_JAMP_lines(me), |
2854 | - ["JAMP(1)=-AMP(1)-AMP(2)-AMP(3)-AMP(4)", |
2855 | - "JAMP(2)=+AMP(5)+AMP(6)+AMP(7)+AMP(8)"]) |
2856 | + ["JAMP(1)=-AMP(1)", |
2857 | + "JAMP(2)=+AMP(2)"]) |
2858 | |
2859 | def test_generate_helas_diagrams_gg_gogo(self): |
2860 | """Testing the v4 helas diagram generation g g > go go, |
2861 | @@ -8631,12 +8592,12 @@ |
2862 | C The process calculated in this file is: |
2863 | C Gamma(3,2,1) |
2864 | C |
2865 | - SUBROUTINE FFV1_1(F2, V3, C, M1, W1, F1) |
2866 | + SUBROUTINE FFV1_1(F2, V3, COUP, M1, W1, F1) |
2867 | IMPLICIT NONE |
2868 | DOUBLE COMPLEX F1(6) |
2869 | DOUBLE COMPLEX F2(6) |
2870 | DOUBLE COMPLEX V3(6) |
2871 | - DOUBLE COMPLEX C |
2872 | + DOUBLE COMPLEX COUP |
2873 | DOUBLE COMPLEX DENOM |
2874 | DOUBLE PRECISION M1, W1 |
2875 | DOUBLE PRECISION P1(0:3) |
2876 | @@ -8653,10 +8614,9 @@ |
2877 | abstract_M.write('/tmp','Fortran') |
2878 | |
2879 | self.assertTrue(os.path.exists('/tmp/FFV1_1.f')) |
2880 | - textfile = open('/tmp/FFV1_1.f','r') |
2881 | + textfile = open('/tmp/FFV1_1.f','r').read() |
2882 | split_sol = solution.split('\n') |
2883 | - for i in range(len(split_sol)): |
2884 | - self.assertEqual(split_sol[i]+'\n', textfile.readline()) |
2885 | + self.assertEqual(split_sol, textfile.split('\n')[:len(split_sol)]) |
2886 | |
2887 | |
2888 | class UFO_model_to_mg4_Test(unittest.TestCase): |
2889 | |
2890 | === modified file 'tests/unit_tests/iolibs/test_helas_call_writers.py' |
2891 | --- tests/unit_tests/iolibs/test_helas_call_writers.py 2011-03-22 00:16:20 +0000 |
2892 | +++ tests/unit_tests/iolibs/test_helas_call_writers.py 2011-04-20 16:57:29 +0000 |
2893 | @@ -493,14 +493,14 @@ |
2894 | |
2895 | wavefunctions = {} |
2896 | # IXXXXXX.Key: (spin, state) |
2897 | - key1 = ((-2, 0), '') |
2898 | + key1 = ((-2, 0), ('',)) |
2899 | wavefunctions[key1] = \ |
2900 | lambda wf: 'CALL IXXXXX(P(0,%d),%s,NHEL(%d),%d*IC(%d),W(1,%d))' % \ |
2901 | (wf.get('number_external'), wf.get('mass'), |
2902 | wf.get('number_external'), -(-1) ** wf.get_with_flow('is_part'), |
2903 | wf.get('number_external'), wf.get('number')) |
2904 | # OXXXXXX.Key: (spin, state) |
2905 | - key2 = ((2, 0), '') |
2906 | + key2 = ((2, 0), ('',)) |
2907 | wavefunctions[key2] = \ |
2908 | lambda wf: 'CALL OXXXXX(P(0,%d),%s,NHEL(%d),%d*IC(%d),W(1,%d))' % \ |
2909 | (wf.get('number_external'), wf.get('mass'), |
2910 | |
2911 | === modified file 'tests/unit_tests/various/test_4fermion_models.py' |
2912 | --- tests/unit_tests/various/test_4fermion_models.py 2011-04-15 04:15:48 +0000 |
2913 | +++ tests/unit_tests/various/test_4fermion_models.py 2011-04-20 16:57:29 +0000 |
2914 | @@ -77,7 +77,6 @@ |
2915 | p)[0] |
2916 | |
2917 | |
2918 | - |
2919 | self.assertAlmostEqual(values['scalar'], values['4ferm'], 3) |
2920 | |
2921 | #=============================================================================== |
2922 | |
2923 | === modified file 'tests/unit_tests/various/test_aloha.py' |
2924 | --- tests/unit_tests/various/test_aloha.py 2011-03-31 17:39:59 +0000 |
2925 | +++ tests/unit_tests/various/test_aloha.py 2011-04-20 16:57:29 +0000 |
2926 | @@ -16,6 +16,7 @@ |
2927 | the output of the Feynman Rules.""" |
2928 | from __future__ import division |
2929 | |
2930 | +import os |
2931 | import time |
2932 | import aloha.aloha_object as aloha_obj |
2933 | import aloha.aloha_lib as aloha_lib |
2934 | @@ -2798,7 +2799,7 @@ |
2935 | # Check that full identification symmetry works |
2936 | helas_suite = create_aloha.AbstractALOHAModel('sm') |
2937 | helas_suite.look_for_symmetries() |
2938 | - solution = {'VVS1': {2: 1}, 'SSS1': {2: 1, 3: 2}, 'VVSS1': {2: 1, 4: 3}, 'VVVV2': {2: 1, 4: 3}, 'SSSS1': {2: 1, 3: 2, 4: 3}} |
2939 | + solution = {'SSSS1': {2: 1, 3: 2, 4: 3}, 'VVVV4': {2: 1, 3: 2, 4: 3}, 'VVV1': {2: 1, 3: 2}, 'VVVV1': {2: 1, 3: 2, 4: 3}, 'VVVV3': {2: 1, 3: 2, 4: 3}, 'VVVV2': {2: 1, 4: 3}, 'SSS1': {2: 1, 3: 2}, 'VVSS1': {2: 1, 4: 3}, 'VVS1': {2: 1}} |
2940 | self.assertEqual(solution, helas_suite.symmetries) |
2941 | |
2942 | def test_has_symmetries(self): |
2943 | @@ -2824,6 +2825,246 @@ |
2944 | |
2945 | base = helas_suite.has_symmetries('VVS1', 3, valid_output=(1, 2)) |
2946 | self.assertEqual(base, None) |
2947 | + |
2948 | + def test_aloha_multiple_lorentz(self): |
2949 | + """ check if the detection of multiple lorentz work """ |
2950 | + |
2951 | + helas_suite = create_aloha.AbstractALOHAModel('sm') |
2952 | + helas_suite.look_for_multiple_lorentz_interactions() |
2953 | + solution = {'FFV2': [('FFV3',), ('FFV4',), ('FFV5',)], 'FFS3': [('FFS4',)]} |
2954 | + self.assertEqual(solution, helas_suite.multiple_lor) |
2955 | + |
2956 | + |
2957 | + def test_aloha_multiple_lorentz_and_symmetry(self): |
2958 | + """ check if the detection of multiple lorentz work """ |
2959 | + |
2960 | + VVS1 = self.Lorentz(name = 'VVS1', |
2961 | + spins = [ 3, 3, 1 ], |
2962 | + structure = 'Metric(1,2)') |
2963 | + |
2964 | + #VVS2 = self.Lorentz(name = 'VVS2', |
2965 | + # spins = [ 3, 3, 1 ], |
2966 | + # structure = 'Metric(2,1)') |
2967 | + |
2968 | + abstract = create_aloha.AbstractRoutineBuilder(VVS1).compute_routine(1) |
2969 | + abstract.add_symmetry(2) |
2970 | + abstract.add_combine(('VVS2',)) |
2971 | + |
2972 | + text = abstract.write(None, 'Fortran') |
2973 | + |
2974 | + goal =""" subroutine VVS1_1(V2, S3, COUP, M1, W1, V1) |
2975 | +implicit none |
2976 | +double complex V1(6) |
2977 | +double complex V2(6) |
2978 | +double complex S3(3) |
2979 | +double complex COUP |
2980 | +double complex denom |
2981 | +double precision M1, W1 |
2982 | +double complex OM1 |
2983 | +double precision P1(0:3) |
2984 | + |
2985 | +V1(5)= V2(5)+S3(2) |
2986 | +V1(6)= V2(6)+S3(3) |
2987 | +P1(0) = - dble(V1(5)) |
2988 | +P1(1) = - dble(V1(6)) |
2989 | +P1(2) = - dimag(V1(6)) |
2990 | +P1(3) = - dimag(V1(5)) |
2991 | +OM1 = 0d0 |
2992 | +if (M1 .ne. 0d0) OM1=1d0/M1**2 |
2993 | + |
2994 | +denom =1d0/(( (M1*( -M1+(0, 1)*W1))+( (P1(0)**2)-(P1(1)**2)-(P1(2)**2)-(P1(3)**2)))) |
2995 | +V1(1)= COUP*denom*(S3(1)*( (OM1*( (0, 1)*(V2(1)*P1(0))+(0, -1)*(V2(2)*P1(1))+(0, -1)*(V2(3)*P1(2))+(0, -1)*(V2(4)*P1(3)))*P1(0))+(0, -1)*V2(1))) |
2996 | +V1(2)= COUP*denom*(S3(1)*( (OM1*( (0, 1)*(V2(1)*P1(0))+(0, -1)*(V2(2)*P1(1))+(0, -1)*(V2(3)*P1(2))+(0, -1)*(V2(4)*P1(3)))*P1(1))+(0, -1)*V2(2))) |
2997 | +V1(3)= COUP*denom*(S3(1)*( (OM1*( (0, 1)*(V2(1)*P1(0))+(0, -1)*(V2(2)*P1(1))+(0, -1)*(V2(3)*P1(2))+(0, -1)*(V2(4)*P1(3)))*P1(2))+(0, -1)*V2(3))) |
2998 | +V1(4)= COUP*denom*(S3(1)*( (OM1*( (0, 1)*(V2(1)*P1(0))+(0, -1)*(V2(2)*P1(1))+(0, -1)*(V2(3)*P1(2))+(0, -1)*(V2(4)*P1(3)))*P1(3))+(0, -1)*V2(4))) |
2999 | +end |
3000 | + |
3001 | + |
3002 | + |
3003 | + subroutine VVS1_2(V2, S3, COUP, M1, W1, V1) |
3004 | +implicit none |
3005 | +double complex V1(6) |
3006 | +double complex V2(6) |
3007 | +double complex S3(3) |
3008 | +double complex COUP |
3009 | +double complex denom |
3010 | +double precision M1, W1 |
3011 | +double complex OM1 |
3012 | +double precision P1(0:3) |
3013 | +call VVS1_1(V2,S3,COUP,M1,W1,V1) |
3014 | +end |
3015 | + |
3016 | + |
3017 | + subroutine VVS1_2_1(V2, S3, COUP1,COUP2, M1, W1, V1) |
3018 | +implicit none |
3019 | +double complex V1(6) |
3020 | +double complex V2(6) |
3021 | +double complex S3(3) |
3022 | +double complex COUP1,COUP2 |
3023 | +double complex denom |
3024 | +double precision M1, W1 |
3025 | +double complex OM1 |
3026 | +double precision P1(0:3) |
3027 | + double complex TMP(6) |
3028 | + integer i |
3029 | + |
3030 | + CALL VVS1_1(V2, S3, COUP1, M1, W1, V1) |
3031 | + CALL VVS2_1(V2, S3, COUP2, M1, W1, TMP) |
3032 | + do i=1,4 |
3033 | + V1(i) = V1(i) + tmp(i) |
3034 | + enddo |
3035 | +end |
3036 | + |
3037 | + subroutine VVS1_2_2(V2, S3, COUP1,COUP2, M1, W1, V1) |
3038 | +implicit none |
3039 | +double complex V1(6) |
3040 | +double complex V2(6) |
3041 | +double complex S3(3) |
3042 | +double complex COUP1,COUP2 |
3043 | +double complex denom |
3044 | +double precision M1, W1 |
3045 | +double complex OM1 |
3046 | +double precision P1(0:3) |
3047 | + double complex TMP(6) |
3048 | + integer i |
3049 | + |
3050 | + CALL VVS1_1(V2, S3, COUP1, M1, W1, V1) |
3051 | + CALL VVS2_1(V2, S3, COUP2, M1, W1, TMP) |
3052 | + do i=1,4 |
3053 | + V1(i) = V1(i) + tmp(i) |
3054 | + enddo |
3055 | +end |
3056 | + |
3057 | +""" |
3058 | + self.assertEqual(text.split('\n'),goal.split('\n')) |
3059 | + |
3060 | + text_h, text_cpp = abstract.write(None, 'CPP') |
3061 | + |
3062 | + goal_h = """#ifndef VVS1_1_guard |
3063 | +#define VVS1_1_guard |
3064 | +#include <complex> |
3065 | +using namespace std; |
3066 | + |
3067 | +void VVS1_1(complex<double> V2[],complex<double> S3[],complex<double> COUP, double M1, double W1, complex<double>V1[]); |
3068 | + |
3069 | +void VVS1_2(complex<double> V2[],complex<double> S3[],complex<double> COUP, double M1, double W1, complex<double>V1[]); |
3070 | + |
3071 | +#endif |
3072 | + |
3073 | +#ifndef VVS1_2_1_guard |
3074 | +#define VVS1_2_1_guard |
3075 | +#include <complex> |
3076 | +using namespace std; |
3077 | + |
3078 | +void VVS1_2_1(complex<double> V2[],complex<double> S3[],complex<double> COUP1, complex <double>COUP2, double M1, double W1, complex<double>V1[]); |
3079 | + |
3080 | +void VVS1_2_2(complex<double> V2[],complex<double> S3[],complex<double> COUP1, complex <double>COUP2, double M1, double W1, complex<double>V1[]); |
3081 | + |
3082 | +#endif""" |
3083 | + goal_cpp = """#include "VVS1_1.h" |
3084 | + |
3085 | +void VVS1_1(complex<double> V2[],complex<double> S3[],complex<double> COUP, double M1, double W1, complex<double>V1[]){ |
3086 | +complex<double> denom; |
3087 | +complex<double> OM1; |
3088 | +double P1[4]; |
3089 | +V1[4]= V2[4]+S3[1]; |
3090 | +V1[5]= V2[5]+S3[2]; |
3091 | +P1[0] = -V1[4].real(); |
3092 | +P1[1] = -V1[5].real(); |
3093 | +P1[2] = -V1[5].imag(); |
3094 | +P1[3] = -V1[4].imag(); |
3095 | +OM1 = 0; |
3096 | +if (M1 != 0) OM1= 1./pow(M1,2); |
3097 | +denom =1./(( (M1*( -M1+complex<double>(0., 1.)*W1))+( (pow(P1[0],2))-(pow(P1[1],2))-(pow(P1[2],2))-(pow(P1[3],2))))); |
3098 | +V1[0]= COUP*denom*(S3[0]*( (OM1*( complex<double>(0., 1.)*(V2[0]*P1[0])+complex<double>(0., -1.)*(V2[1]*P1[1])+complex<double>(0., -1.)*(V2[2]*P1[2])+complex<double>(0., -1.)*(V2[3]*P1[3]))*P1[0])+complex<double>(0., -1.)*V2[0])); |
3099 | +V1[1]= COUP*denom*(S3[0]*( (OM1*( complex<double>(0., 1.)*(V2[0]*P1[0])+complex<double>(0., -1.)*(V2[1]*P1[1])+complex<double>(0., -1.)*(V2[2]*P1[2])+complex<double>(0., -1.)*(V2[3]*P1[3]))*P1[1])+complex<double>(0., -1.)*V2[1])); |
3100 | +V1[2]= COUP*denom*(S3[0]*( (OM1*( complex<double>(0., 1.)*(V2[0]*P1[0])+complex<double>(0., -1.)*(V2[1]*P1[1])+complex<double>(0., -1.)*(V2[2]*P1[2])+complex<double>(0., -1.)*(V2[3]*P1[3]))*P1[2])+complex<double>(0., -1.)*V2[2])); |
3101 | +V1[3]= COUP*denom*(S3[0]*( (OM1*( complex<double>(0., 1.)*(V2[0]*P1[0])+complex<double>(0., -1.)*(V2[1]*P1[1])+complex<double>(0., -1.)*(V2[2]*P1[2])+complex<double>(0., -1.)*(V2[3]*P1[3]))*P1[3])+complex<double>(0., -1.)*V2[3])); |
3102 | +} |
3103 | + |
3104 | +void VVS1_2(complex<double> V2[],complex<double> S3[],complex<double> COUP, double M1, double W1, complex<double>V1[]){ |
3105 | +VVS1_1(V2,S3,COUP,M1,W1,V1); |
3106 | +} |
3107 | + |
3108 | +#include "VVS1_2_1.h" |
3109 | + |
3110 | +void VVS1_2_1(complex<double> V2[],complex<double> S3[],complex<double> COUP1, complex<double>COUP2, double M1, double W1, complex<double>V1[]){ |
3111 | +complex<double> tmp[6]; |
3112 | + int i = 0; |
3113 | + |
3114 | +VVS1_1(V2, S3, COUP1, M1, W1, V1); |
3115 | +VVS2_1(V2, S3, COUP2, M1, W1, tmp); |
3116 | + while (i < 4) |
3117 | + { |
3118 | + V1[i] = V1[i] + tmp[i]; |
3119 | + i++; |
3120 | + } |
3121 | +} |
3122 | + |
3123 | +#include "VVS1_2_2.h" |
3124 | + |
3125 | +void VVS1_2_2(complex<double> V2[],complex<double> S3[],complex<double> COUP1, complex<double>COUP2, double M1, double W1, complex<double>V1[]){ |
3126 | +complex<double> tmp[6]; |
3127 | + int i = 0; |
3128 | + |
3129 | +VVS1_1(V2, S3, COUP1, M1, W1, V1); |
3130 | +VVS2_1(V2, S3, COUP2, M1, W1, tmp); |
3131 | + while (i < 4) |
3132 | + { |
3133 | + V1[i] = V1[i] + tmp[i]; |
3134 | + i++; |
3135 | + } |
3136 | +} |
3137 | + |
3138 | +""" |
3139 | + |
3140 | + self.assertEqual(text_h.split('\n'),goal_h.split('\n')) |
3141 | + self.assertEqual(text_cpp.split('\n'),goal_cpp.split('\n')) |
3142 | + |
3143 | + |
3144 | + text = abstract.write(None, 'Python') |
3145 | + goal = """import wavefunctions |
3146 | +def VVS1_1(V2, S3, COUP, M1, W1): |
3147 | + V1 = wavefunctions.WaveFunction(size=6) |
3148 | + V1[4] = V2[4]+S3[1] |
3149 | + V1[5] = V2[5]+S3[2] |
3150 | + P1 = [-complex(V1[4]).real, \\ |
3151 | + - complex(V1[5]).real, \\ |
3152 | + - complex(V1[5]).imag, \\ |
3153 | + - complex(V1[4]).imag] |
3154 | + OM1 = 0.0 |
3155 | + if (M1): OM1=1.0/M1**2 |
3156 | + denom =1.0/(( (M1*( -M1+1j*W1))+( (P1[0]**2)-(P1[1]**2)-(P1[2]**2)-(P1[3]**2)))) |
3157 | + V1[0]= COUP*denom*(S3[0]*( (OM1*( 1j*(V2[0]*P1[0])-1j*(V2[1]*P1[1])-1j*(V2[2]*P1[2])-1j*(V2[3]*P1[3]))*P1[0])-1j*V2[0])) |
3158 | + V1[1]= COUP*denom*(S3[0]*( (OM1*( 1j*(V2[0]*P1[0])-1j*(V2[1]*P1[1])-1j*(V2[2]*P1[2])-1j*(V2[3]*P1[3]))*P1[1])-1j*V2[1])) |
3159 | + V1[2]= COUP*denom*(S3[0]*( (OM1*( 1j*(V2[0]*P1[0])-1j*(V2[1]*P1[1])-1j*(V2[2]*P1[2])-1j*(V2[3]*P1[3]))*P1[2])-1j*V2[2])) |
3160 | + V1[3]= COUP*denom*(S3[0]*( (OM1*( 1j*(V2[0]*P1[0])-1j*(V2[1]*P1[1])-1j*(V2[2]*P1[2])-1j*(V2[3]*P1[3]))*P1[3])-1j*V2[3])) |
3161 | + return V1 |
3162 | + |
3163 | + |
3164 | +def VVS1_2(V2, S3, COUP, M1, W1): |
3165 | + return VVS1_1(V2,S3,COUP,M1,W1) |
3166 | + |
3167 | +def VVS1_2_1(V2, S3, COUP1,COUP2, M1, W1): |
3168 | + |
3169 | + |
3170 | + V1 = VVS1_1(V2, S3, COUP1, M1, W1) |
3171 | + tmp = VVS2_1(V2, S3, COUP2, M1, W1) |
3172 | + for i in range(4): |
3173 | + V1[i] += tmp[i] |
3174 | + return V1 |
3175 | + |
3176 | +def VVS1_2_2(V2, S3, COUP1,COUP2, M1, W1): |
3177 | + |
3178 | + |
3179 | + V1 = VVS1_1(V2, S3, COUP1, M1, W1) |
3180 | + tmp = VVS2_1(V2, S3, COUP2, M1, W1) |
3181 | + for i in range(4): |
3182 | + V1[i] += tmp[i] |
3183 | + return V1 |
3184 | + |
3185 | +""" |
3186 | + self.assertEqual(text.split('\n'),goal.split('\n')) |
3187 | |
3188 | |
3189 | def test_full_sm_aloha(self): |
3190 | @@ -2852,17 +3093,77 @@ |
3191 | spin_solution = spin_index[helas.spins[output_part -1]] |
3192 | self.assertEqual(abstract.expr.numerator.nb_spin, spin_solution, \ |
3193 | error % name) |
3194 | + |
3195 | + def test_multiple_lorentz_subset(self): |
3196 | + """test if we create the correct set of routine/files for multiple lorentz""" |
3197 | + |
3198 | + helas_suite = create_aloha.AbstractALOHAModel('sm') |
3199 | + requested_routines=[(('FFS1','FFS2') , (), 0), |
3200 | + (('FFV1',) , (), 0), |
3201 | + (('FFV1','FFV2') , (1,), 0)] |
3202 | + |
3203 | + helas_suite.compute_subset(requested_routines) |
3204 | + |
3205 | + # Check that the 5 base routines are created |
3206 | + # FFS1, FFS2, FFV1, FFV1C1, FFV2C1 |
3207 | + self.assertEqual(len(helas_suite), 5) |
3208 | + |
3209 | + # Check that FFS1 and FFV1C1 are correctly connected to the associate |
3210 | + #lorentz |
3211 | + linked = helas_suite[('FFS1',0)].combined |
3212 | + self.assertEqual(linked, [('FFS2',)]) |
3213 | + linked = helas_suite[('FFV1C1',0)].combined |
3214 | + self.assertEqual(linked, [('FFV2',)]) |
3215 | + linked = helas_suite[('FFV1',0)].combined |
3216 | + self.assertEqual(linked, []) |
3217 | + |
3218 | + # Check that the file are correctly written |
3219 | + os.system('rm -r /tmp/mg5 &> /dev/null; mkdir /tmp/mg5 &> /dev/null') |
3220 | + helas_suite.write('/tmp/mg5', 'Fortran') |
3221 | + |
3222 | + content = set(os.listdir('/tmp/mg5')) |
3223 | + self.assertEqual(content, set(['FFS1_0.f', 'FFS2_0.f', 'FFV1_0.f', |
3224 | + 'FFV1C1_0.f','FFV2C1_0.f', 'FFS1_2_0.f', |
3225 | + 'FFV1C1_2_0.f'])) |
3226 | + |
3227 | + # Check the content of FFV1__FFV2C1_0.f |
3228 | + fsock = open('/tmp/mg5/FFV1C1_2_0.f') |
3229 | + goal = """C This File is Automatically generated by ALOHA |
3230 | +C |
3231 | + SUBROUTINE FFV1C1_2_0(F1,F2,V3,COUP1,COUP2,VERTEX) |
3232 | + IMPLICIT NONE |
3233 | + DOUBLE COMPLEX F1(6) |
3234 | + DOUBLE COMPLEX F2(6) |
3235 | + DOUBLE COMPLEX V3(6) |
3236 | + DOUBLE COMPLEX COUP1,COUP2 |
3237 | + DOUBLE COMPLEX VERTEX |
3238 | + DOUBLE COMPLEX TMP |
3239 | + |
3240 | + |
3241 | + CALL FFV1C1_0(F1, F2, V3, COUP1, VERTEX) |
3242 | + CALL FFV2C1_0(F1, F2, V3, COUP2, TMP) |
3243 | + VERTEX = VERTEX + TMP |
3244 | + END |
3245 | + |
3246 | + |
3247 | +""" |
3248 | + self.assertEqual(fsock.read().split('\n'), goal.split('\n')) |
3249 | + |
3250 | + |
3251 | + |
3252 | + |
3253 | + |
3254 | |
3255 | def test_mssm_subset_creation(self): |
3256 | """ test the creation of subpart of ALOHA routines |
3257 | including clash routines """ |
3258 | helas_suite = create_aloha.AbstractALOHAModel('mssm') |
3259 | |
3260 | - requested_routines=[('FFV1' , (), 0), |
3261 | - ('FFV1', (), 2), |
3262 | - ('FFV1', (1,), 0), |
3263 | - ('FFV2', (1,), 3), |
3264 | - ('VVV1', (), 3)] |
3265 | + requested_routines=[(('FFV1',) , (), 0), |
3266 | + (('FFV1',), (), 2), |
3267 | + (('FFV1',), (1,), 0), |
3268 | + (('FFV2',), (1,), 3), |
3269 | + (('VVV1',), (), 3)] |
3270 | |
3271 | helas_suite.compute_subset(requested_routines) |
3272 | self.assertEqual(len(helas_suite), 5) |
3273 | @@ -3008,7 +3309,7 @@ |
3274 | and test_export_pythia""" |
3275 | |
3276 | |
3277 | - def test_reorder_call_listFFVV(self): |
3278 | + def old_test_reorder_call_listFFVV(self): |
3279 | |
3280 | FFVV = UFOLorentz(name = 'FFVV', |
3281 | spins = [ 2, 2, 3, 3]) |
3282 | @@ -3021,7 +3322,7 @@ |
3283 | new_call = writer.reorder_call_list(call_list, 1, 2) |
3284 | self.assertEqual(['F2', 'V3', 'V4'], new_call) |
3285 | |
3286 | - def test_reorder_call_listFVVV(self): |
3287 | + def old_test_reorder_call_listFVVV(self): |
3288 | FVVV = UFOLorentz(name = 'FVVV', |
3289 | spins = [ 2, 3, 3, 3]) |
3290 | |
3291 | @@ -3041,7 +3342,7 @@ |
3292 | new_call = writer.reorder_call_list(call_list, 2, 4) |
3293 | self.assertEqual(['F1', 'V4', 'V3'], new_call) |
3294 | |
3295 | - def test_reorder_call_listVVVV(self): |
3296 | + def old_test_reorder_call_listVVVV(self): |
3297 | VVVV = UFOLorentz(name = 'VVVV', |
3298 | spins = [ 3, 3, 3, 3]) |
3299 | |
3300 | @@ -3092,7 +3393,7 @@ |
3301 | new_call = writer.reorder_call_list(call_list, 3, 4) |
3302 | self.assertEqual(['V1', 'V2', 'V4'], new_call) |
3303 | |
3304 | - def test_reorder_call_listUVVS(self): |
3305 | + def old_test_reorder_call_listUVVS(self): |
3306 | UVVS = UFOLorentz(name = 'UVVS', |
3307 | spins = [ 2, 3, 3, 1]) |
3308 | |
3309 | @@ -3144,7 +3445,7 @@ |
3310 | """ test that python writer works """ |
3311 | |
3312 | solution ="""import wavefunctions |
3313 | -def SSS1_1(S2, S3, C, M1, W1): |
3314 | +def SSS1_1(S2, S3, COUP, M1, W1): |
3315 | S1 = wavefunctions.WaveFunction(size=3) |
3316 | S1[1] = S2[1]+S3[1] |
3317 | S1[2] = S2[2]+S3[2] |
3318 | @@ -3153,12 +3454,17 @@ |
3319 | - complex(S1[2]).imag, \\ |
3320 | - complex(S1[1]).imag] |
3321 | denom =1.0/(( (M1*( -M1+1j*W1))+( (P1[0]**2)-(P1[1]**2)-(P1[2]**2)-(P1[3]**2)))) |
3322 | - S1[0]= C*denom*1j*(S3[0]*S2[0]) |
3323 | + S1[0]= COUP*denom*1j*(S3[0]*S2[0]) |
3324 | return S1 |
3325 | -def SSS1_2(S2, S3, C, M1, W1): |
3326 | - return SSS1_1(S2,S3,C,M1,W1) |
3327 | -def SSS1_3(S2, S3, C, M1, W1): |
3328 | - return SSS1_1(S3,S2,C,M1,W1)""" |
3329 | + |
3330 | + |
3331 | +def SSS1_2(S2, S3, COUP, M1, W1): |
3332 | + return SSS1_1(S2,S3,COUP,M1,W1) |
3333 | + |
3334 | +def SSS1_3(S2, S3, COUP, M1, W1): |
3335 | + return SSS1_1(S2,S3,COUP,M1,W1) |
3336 | + |
3337 | +""" |
3338 | |
3339 | SSS = UFOLorentz(name = 'SSS1', |
3340 | spins = [ 1, 1, 1 ], |
3341 | @@ -3172,8 +3478,7 @@ |
3342 | |
3343 | split_solution = solution.split('\n') |
3344 | split_routine = routine.split('\n') |
3345 | - for i,line in enumerate(split_routine): |
3346 | - self.assertEqual(split_solution[i],line) |
3347 | + self.assertEqual(split_solution, split_routine) |
3348 | self.assertEqual(len(split_routine), len(split_solution)) |
3349 | |
3350 | |
3351 | @@ -3191,14 +3496,16 @@ |
3352 | |
3353 | |
3354 | solution = """import wavefunctions |
3355 | -def FFV2C1_0(F1,F2,V3,C): |
3356 | - vertex = C*( (F1[3]*( (F2[0]*( -1j*V3[1]-V3[2]))+(F2[1]*( 1j*V3[0]+1j*V3[3]))))+(F1[2]*( (F2[0]*( 1j*V3[0]-1j*V3[3]))+(F2[1]*( -1j*V3[1]+V3[2]))))) |
3357 | - return vertex""" |
3358 | +def FFV2C1_0(F1,F2,V3,COUP): |
3359 | + vertex = COUP*( (F1[3]*( (F2[0]*( -1j*V3[1]-V3[2]))+(F2[1]*( 1j*V3[0]+1j*V3[3]))))+(F1[2]*( (F2[0]*( 1j*V3[0]-1j*V3[3]))+(F2[1]*( -1j*V3[1]+V3[2]))))) |
3360 | + return vertex |
3361 | + |
3362 | + |
3363 | +""" |
3364 | |
3365 | split_solution = solution.split('\n') |
3366 | split_routine = routine.split('\n') |
3367 | - for i,line in enumerate(split_routine): |
3368 | - self.assertEqual(split_solution[i],line) |
3369 | + self.assertEqual(split_solution,split_routine) |
3370 | self.assertEqual(len(split_routine), len(split_solution)) |
3371 | |
3372 |
Hello Olivier,
This is really cool! I do have a couple of questions about the code:
1) Did you add the check in the ALOHA routines if COUP == 0 (in that case exit with zero wf/amp)?
This check should not be in the combined routines of course, only in the basic routines.
2) In aloha_writers, you do g.split( 'C',1)[ 1] r'''^[STFV\ d_]*[_C\ d]*_\d% s''' % file_ext)"
# Define which part of the routine should be called
if 'C' in self.namestring:
addon = 'C' +self.namestrin
else:
addon = '_%s' % self.offshell
What if a used calls the Lorentz something with a 'C' in the name?
(this might apply in other places too)
Update: " alohafile_pattern = re.compile(
So in fact you are not allowing the user freedom to select lorentz names outside of the
FR defined ones? This of course solves the problem.
3) + # Two possible scheme FFV1C1_2_X or FFV1__FFV2C1_X
Why use double "_" for the combined name instead of the slightly better FFV1_FFV2C1_X?
That's the first pass, I'll continue after lunch :-)
Johan