1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Definitions of the objects needed both for MadFKS from real
17 and MadFKS from born"""
18
19 import madgraph.core.base_objects as MG
20 import madgraph.core.helas_objects as helas_objects
21 import madgraph.core.diagram_generation as diagram_generation
22 import madgraph.core.color_amp as color_amp
23 import madgraph.core.color_algebra as color_algebra
24 from operator import itemgetter
25 import copy
26 import logging
27 import array
28 import fractions
33 """Exception for MadFKS"""
34 pass
35
38 """Modified diagram tags to be used to link born and real configurations.
39 """
40
41 @staticmethod
43 """Returns the default end link for a leg: ((id, number), number).
44 Note that the number is not taken into account if tag comparison,
45 but is used only to extract leg permutations.
46 """
47 return [((leg.get('id'), leg.get('number')), leg.get('number'))]
48
51 """finds the real configurations that match the born ones, i.e. for
52 each born configuration, the real configuration that has the ij ->
53 i j splitting. i, j and ij are integers, and refer to the leg
54 position in the real process (i, j) and in the born process (ij).
55 """
56
57 id_ij = born_amp['process']['legs'][ij - 1]['id']
58 nlegs_b = len(born_amp['process']['legs'])
59 nlegs_r = len(real_amp['process']['legs'])
60 if nlegs_r - nlegs_b != 1:
61 raise FKSProcessError('Inconsistent number of born and real legs: %d %d' % (nlegs_b, nlegs_r))
62
63
64 shift_dict = {}
65 for ir in range(1, nlegs_r + 1):
66 shift = 0
67 if ir > j:
68 shift += 1
69 if ir > i:
70 shift += 1
71 if ir > ij and ij <= max(i,j):
72 shift -= 1
73 shift_dict[ir] = ir - shift
74
75
76 minvert = min([max([len(vert.get('legs')) \
77 for vert in diag.get('vertices')]) \
78 for diag in born_amp.get('diagrams')])
79
80 born_confs = []
81 real_confs = []
82
83 k=0
84 for diag in born_amp.get('diagrams'):
85 if any([len(vert.get('legs')) > minvert for vert in
86 diag.get('vertices')]):
87 continue
88 else:
89 born_confs.append({'number' : k, 'diagram' : diag})
90 k=k+1
91
92 k=0
93 for diag in real_amp.get('diagrams'):
94 if any([len(vert.get('legs')) > minvert \
95 for vert in diag.get('vertices')]):
96 continue
97 else:
98 real_confs.append({'number': k, 'diagram': diag})
99 k=k+1
100
101 good_diags = []
102
103
104
105
106 real_confs_new = copy.deepcopy(real_confs)
107 for diag in real_confs_new:
108 for vert in diag['diagram'].get('vertices'):
109 vert_legs = [l.get('number') for l in vert.get('legs')]
110 vert_ids = [l.get('id') for l in vert.get('legs')]
111 if (i in vert_legs and not j in vert_legs) or \
112 (j in vert_legs and not i in vert_legs):
113 break
114
115 if i in vert_legs and j in vert_legs:
116 vert_ids.remove(vert_ids[vert_legs.index(i)])
117 vert_legs.remove(i)
118 vert_ids.remove(vert_ids[vert_legs.index(j)])
119 vert_legs.remove(j)
120 last_leg = vert_legs[0]
121
122
123 if abs(vert_ids[0]) == abs(id_ij):
124 diag['diagram']['vertices'].remove(vert)
125 good_diags.append({'diagram': diag['diagram'],
126 'leg_ij': last_leg,
127 'number': diag['number']})
128 break
129
130
131
132
133
134
135
136
137 legs = []
138
139 for d in good_diags:
140 for v in d['diagram'].get('vertices'):
141 for l in v.get('legs'):
142 if l not in legs:
143 legs.append(copy.copy(l))
144
145
146
147
148 for ir in range(1, nlegs_r + 1):
149 for good_diag in good_diags:
150 for vert in good_diag['diagram'].get('vertices'):
151 for l in vert.get('legs'):
152 if l.get('number') == ir:
153 l.set('number', shift_dict[l.get('number')])
154
155
156 if len(good_diags) == 1 and len(born_confs) == 1:
157 return [{'real_conf': good_diags[0]['number'],
158 'born_conf': born_confs[0]['number']}]
159
160
161 born_tags = [FKSDiagramTag(d['diagram'],
162 born_amp.get('process').get('model')) \
163 for d in born_confs]
164
165
166 real_tags = [FKSDiagramTag(d['diagram'],
167 real_amp.get('process').get('model')) \
168 for d in good_diags ]
169 real_tags = []
170 for d in good_diags:
171 tag = FKSDiagramTag(d['diagram'], real_amp.get('process').get('model'))
172 if not tag in real_tags:
173 real_tags.append(tag)
174
175
176 if len(born_tags) != len(real_tags):
177 print '\n'.join([str(r) for r in real_tags]) + '\n'
178 raise FKSProcessError('Cannot map born/real configurations between \
179 %s and %s (i,j=%d,%d): not same number of configurations: %d %d' % \
180 (born_amp.get('process').nice_string().replace('Process:',''),
181 real_amp.get('process').nice_string().replace('Process:',''),
182 i,j,
183 len(born_tags),
184 len(real_tags)))
185
186 links = []
187 for ib, btag in enumerate(born_tags):
188 try:
189 ir = real_tags.index(btag)
190 links.append({'real_conf': good_diags[ir]['number'],
191 'born_conf': born_confs[ib]['number']})
192 real_tags.remove(btag)
193 good_diags.pop(ir)
194 except ValueError:
195 print real_tags, i, j, ij
196 print '\n'.join( d['diagram'].nice_string() for d in good_diags)
197 raise FKSProcessError('Linking %s to %s: could not link born diagram %s' % \
198 (born_amp.get('process').nice_string().replace('Process:',''),
199 real_amp.get('process').nice_string().replace('Process:',''),
200 born_confs[ib]['diagram'].nice_string()) )
201
202 return links
203
207 """Takes an amplitude as input, and returns a dictionary with the
208 orders of the couplings.
209 """
210 assert isinstance(amp, diagram_generation.Amplitude)
211 orders = {}
212 for diag in amp.get('diagrams'):
213 for order, value in diag.get('orders').items():
214 if value != 0 or order in amp['process']['orders'].keys():
215 try:
216 orders[order] = max(orders[order], value)
217 except KeyError:
218 orders[order] = value
219 return orders
220
223 """Finds the possible splittings corresponding to leg
224 """
225 if dict == {}:
226 dict = find_pert_particles_interactions(model, pert)
227 splittings = []
228
229
230 if leg.get('id') in dict['pert_particles']:
231 part = model.get('particle_dict')[leg.get('id')]
232 antipart = model.get('particle_dict')[part.get_anti_pdg_code()]
233 for ii in dict['interactions']:
234
235 parts = copy.deepcopy(ii['particles'])
236 nsoft = 0
237 if part in parts:
238
239 parts.pop(parts.index(antipart))
240 for p in parts:
241 if p.get_pdg_code() in dict['soft_particles']:
242 nsoft += 1
243 if nsoft >= 1:
244 splittings.extend(split_leg(leg, parts, model))
245 return splittings
246
249 """Splits the leg into parts, and returns the two new legs.
250 """
251
252 split = []
253
254 if leg['state'] :
255 split.append([])
256 for part in parts:
257 split[-1].append(to_fks_leg({'state': True, \
258 'id': part.get_pdg_code()},model))
259 ij_final(split[-1])
260
261
262 else:
263 if parts[0] != parts[1]:
264 for part in parts:
265 cparts = copy.deepcopy(parts)
266 split.append([\
267 to_fks_leg({'state': False,
268 'id': cparts.pop(cparts.index(part)).get_pdg_code(),
269 'fks': 'j'}, model),
270 to_fks_leg({'state': True,
271 'id': cparts[0].get_anti_pdg_code(),
272 'fks': 'i'}, model)\
273 ])
274 else:
275 split.append([\
276 to_fks_leg({'state': False,
277 'id': parts[0].get_pdg_code(),
278 'fks': 'j'}, model),
279 to_fks_leg({'state': True,
280 'id': parts[1].get_anti_pdg_code(),
281 'fks': 'i'}, model)])
282 return split
283
286 """given a pair of legs in the final state, assigns the i/j fks id
287 NOTE: the j partons is always put before the i one
288 """
289
290
291
292 if len(pair) == 2:
293 for i in range(len(pair)):
294 set = 0
295 if (pair[i]['massless'] and pair[i]['self_antipart']) or \
296 (not pair[i]['is_part'] and pair[1-i]['is_part'] and\
297 (pair[i]['spin']+pair[1-i]['spin'])%2==0) and not set:
298 pair[i]['fks'] = 'i'
299 pair[1-i]['fks'] = 'j'
300
301 if i < 1 - i:
302 pair.reverse()
303 set = 1
304
306 """Returns a new leglist with leg splitted into split.
307 The convention is to remove leg ij, replace it with leg j, and put
308 i at the end of the group of legs with the same color(charge) representation
309 """
310 if pert =='QCD':
311 color = 'color'
312 elif pert == 'QED':
313 color = 'charge'
314 else:
315 raise FKSProcessError, "Only QCD or QED is allowed not %s" % pert
316
317 leglist = FKSLegList(copy.deepcopy(leglist_orig))
318
319 for i in range(len(leglist)):
320 if leglist[-i - 1].get('state'):
321 firstfinal = len(leglist) - i - 1
322
323 leglist[leglist.index(leg)] = split[0]
324
325 col_maxindex = {}
326 mass_col_maxindex = {}
327 for col in set([l[color] for l in leglist[firstfinal:] if l['massless']]):
328 col_maxindex[col] = max([0] + [leglist.index(l) for l in leglist[firstfinal:]\
329 if l[color] == col and l['massless']])
330 for col in set([abs(l[color]) for l in leglist[firstfinal:] if not l['massless']]):
331 mass_col_maxindex[col] = max([0] + [leglist.index(l) for l in leglist[firstfinal:]\
332 if abs(l[color]) == col and not l['massless']])
333
334 if pert == 'QCD':
335 for col in copy.copy(col_maxindex.keys()):
336 if abs(col) > abs(split[1][color]):
337 del col_maxindex[col]
338
339
340
341
342 if split[1]['is_part'] and not split[1]['self_antipart']:
343
344
345
346
347 try:
348 del col_maxindex[-split[1][color]]
349 except KeyError:
350 pass
351
352 leglist.insert(max(col_maxindex.values() + mass_col_maxindex.values() + [firstfinal - 1] ) + 1, split[1])
353
354
355
356
357
358
359
360
361
362
363
364 for i, leg in enumerate(leglist):
365 leg['number'] = i + 1
366 return leglist
367
368
369 -def combine_ij( i, j, model, dict, pert='QCD'):
370 """checks whether FKSlegs i and j can be combined together in the given model
371 and with given perturbation order and if so combines them into ij.
372 If dict is empty it is initialized with find_pert_particles_interactions
373 """
374 if dict == {}:
375 dict = find_pert_particles_interactions(model, pert)
376 ij = []
377 num = copy.copy(min(i.get('number'), j.get('number')))
378
379
380 not_double_counting = (j.get('spin') == 3 and j.get('massless') and
381 i.get('spin') == 3 and i.get('massless')) or \
382 j.get('spin') != 3 or not j.get('massless') or \
383 not j.get('state')
384
385
386
387 if j.get('state') and j.get('id') == - i.get('id'):
388 not_double_counting = not_double_counting and j.get('id') >0
389
390 if i.get('id') in dict['soft_particles'] and \
391 j.get('id') in dict['pert_particles'] and \
392 i.get('state') and not_double_counting:
393 for int in dict['interactions']:
394 parts= copy.copy(int['particles'])
395
396 try:
397 parts.remove(model.get('particle_dict')[i.get('id')])
398 except ValueError:
399 continue
400
401
402 if j.get('state'):
403 j_id = j.get('id')
404 else:
405 j_id = model.get('particle_dict')[j.get('id')].get_anti_pdg_code()
406 try:
407 parts.remove(model.get('particle_dict')[j_id])
408 except ValueError:
409 continue
410
411
412 if j.get('state'):
413 ij.append(MG.Leg({
414 'id': parts[0].get_anti_pdg_code(),
415 'state': True,
416 'number': num}))
417 else:
418 ij.append(MG.Leg({
419 'id': parts[0].get_pdg_code(),
420 'state': False,
421 'number': num}))
422 return to_fks_legs(ij, model)
423
424
425 -def find_pert_particles_interactions(model, pert_order = 'QCD'):
426 """given a model and pert_order, returns a dictionary with as entries:
427 --interactions : the interactions of order pert_order
428 --pert_particles : pdgs of particles taking part to interactions
429 --soft_particles : pdgs of massless particles in pert_particles
430 """
431
432 ghost_list = []
433 ghost_list += [ p.get_pdg_code() for p in model.get('particles') if p.get('ghost')]
434 qcd_inter = MG.InteractionList()
435 pert_parts = []
436 soft_parts = []
437 for i, ii in model.get('interaction_dict').items():
438
439
440 if ii.get('orders') == {pert_order:1} and len(ii['particles']) == 3 :
441 masslist = [p.get('mass').lower() for p in ii['particles']]
442
443
444
445
446 try:
447 masslist.remove('zero')
448 except ValueError:
449 continue
450 if len(set(masslist)) == 1 and not \
451 any( [ p.get_pdg_code() in ghost_list for p in ii['particles']]) :
452 qcd_inter.append(ii)
453 for pp in ii['particles']:
454 pert_parts.append(pp.get_pdg_code())
455 if pp['mass'].lower() == 'zero':
456 soft_parts.append(pp.get_pdg_code())
457
458 return {'interactions': sorted(qcd_inter),
459 'pert_particles': sorted(set(pert_parts)),
460 'soft_particles': sorted(set(soft_parts))}
461
464 """insert the color links in col_obj: returns a list of dictionaries
465 (one for each link) with the following entries:
466 --link: the numbers of the linked legs
467 --link_basis: the linked color basis
468 --link_matrix: the color matrix created from the original basis and the linked one
469 """
470 assert isinstance(col_basis, color_amp.ColorBasis)
471 assert isinstance(col_obj, list)
472 result =[]
473 for link in links:
474 this = {}
475
476 l =[]
477 for leg in link['legs']:
478 l.append(leg.get('number'))
479 this['link'] = l
480
481
482
483
484
485 this_col_obj = []
486 for old_dict in col_obj:
487 new_dict = dict(old_dict)
488 for k, string in new_dict.items():
489 new_dict[k] = string.create_copy()
490 for col in new_dict[k]:
491 for ind in col:
492 for pair in link['replacements']:
493 if ind == pair[0]:
494 col[col.index(ind)] = pair[1]
495 new_dict[k].product(link['string'])
496 this_col_obj.append(new_dict)
497 basis_link = color_amp.ColorBasis()
498 for ind, new_dict in enumerate(this_col_obj):
499 basis_link.update_color_basis(new_dict, ind)
500
501 this['link_basis'] = basis_link
502 this['link_matrix'] = color_amp.ColorMatrix(col_basis,basis_link)
503 result.append(this)
504 basis_orig = color_amp.ColorBasis()
505 for ind, new_dict in enumerate(col_obj):
506 basis_orig.update_color_basis(new_dict, ind)
507
508 for link in result:
509 link['orig_basis'] = basis_orig
510 return result
511
515 """Finds all the possible color(charge) links between any
516 two legs of the born.
517 If symm is true, only half of the color links are generated, those
518 for which leg1['number'] <= leg2['number']
519 """
520 if pert == 'QCD':
521 color = 'color'
522 zero = 1
523 elif pert == 'QED':
524 color = 'charge'
525 zero = 0.
526 else:
527 raise FKSProcessError,"Only QCD or QED is allowed not %s" % pert
528 color_links = []
529 for leg1 in leglist:
530 for leg2 in leglist:
531
532 if (leg1.get(color) != zero and leg2.get(color) != zero) \
533 and (leg1 != leg2 or not leg1.get('massless')):
534 if not symm or leg1['number'] <= leg2['number']:
535 col_dict = legs_to_color_link_string(leg1,leg2,pert = pert)
536 color_links.append({
537 'legs': [leg1, leg2],
538 'string': col_dict['string'],
539 'replacements': col_dict['replacements']})
540
541 return color_links
542
545 """given two FKSlegs, returns a dictionary containing:
546 --string: the color link between the two particles, to be appended to
547 the old color string
548 extra minus or 1/2 factor are included as it was done in MadDipole
549 --replacements: a pair of lists containing the replacements of the color
550 indices in the old string to match the link
551 """
552
553
554
555 legs = FKSLegList([leg1, leg2])
556 dict = {}
557 min_index = -3000
558 iglu = min_index*2
559 string = color_algebra.ColorString()
560 replacements = []
561 if pert == 'QCD':
562 if leg1 != leg2:
563 for leg in legs:
564 min_index -= 1
565 num = leg.get('number')
566 replacements.append([num, min_index])
567 icol = 1
568 if not leg.get('state'):
569 icol = - 1
570 if leg.get('color') * icol == 3:
571 string.product(color_algebra.ColorString([
572 color_algebra.T(iglu, num, min_index)]))
573 string.coeff = string.coeff * (-1)
574 elif leg.get('color') * icol == - 3:
575 string.product(color_algebra.ColorString([
576 color_algebra.T(iglu, min_index, num)]))
577 elif leg.get('color') == 8:
578 string.product(color_algebra.ColorString(init_list = [
579 color_algebra.f(min_index,iglu,num)],
580 is_imaginary =True))
581
582 else:
583 icol = 1
584 if not leg1.get('state'):
585 icol = - 1
586 num = leg1.get('number')
587 replacements.append([num, min_index -1])
588 if leg1.get('color') * icol == 3:
589 string = color_algebra.ColorString(
590 [color_algebra.T(iglu, iglu, num, min_index -1)])
591 elif leg1.get('color') * icol == - 3:
592 string = color_algebra.ColorString(
593 [color_algebra.T(iglu, iglu, min_index-1, num)])
594 elif leg1.get('color') == 8:
595 string = color_algebra.ColorString(init_list = [
596 color_algebra.f(min_index-1,iglu,min_index)],
597 is_imaginary =True)
598 string.product(color_algebra.ColorString(init_list = [
599 color_algebra.f(min_index,iglu,num)],
600 is_imaginary =True))
601 string.coeff = string.coeff * fractions.Fraction(1, 2)
602
603 elif pert == 'QED':
604 for leg in legs:
605
606 string.coeff = string.coeff * fractions.Fraction(leg['charge']*3.)*\
607 fractions.Fraction(1,3)
608 else:
609 raise FKSProcessError,"Only QCD or QED is allowed not %s"% pert
610
611 dict['replacements'] = replacements
612 dict['string'] = string
613 return dict
614
617 """Given a process, this function returns the same process
618 but with sorted FKSLegs.
619 """
620 leglist = to_fks_legs(process.get('legs'), process.get('model'))
621 leglist.sort(pert = pert)
622 for n, leg in enumerate(leglist):
623 leg['number'] = n + 1
624 process['legs'] = leglist
625
626 process['legs_with_decays']=MG.LegList()
627
628 return process
629
632 """Given a FKSLeg, returns the original Leg.
633 """
634 leg = MG.Leg( \
635 {'id': fksleg.get('id'),
636 'number': fksleg.get('number'),
637 'state': fksleg.get('state'),
638 'from_group': fksleg.get('from_group'),
639 })
640 return leg
641
644 """Given a FKSLegList, returns the corresponding LegList.
645 """
646 leglist = MG.LegList()
647 for leg in fkslegs:
648 leglist.append(to_leg(leg))
649 return leglist
650
653 """Given a leg or a dict with Leg entries,
654 adds color, spin and massless entries, according to model"""
655 fksleg = FKSLeg(leg)
656 part = model.get('particle_dict')[leg['id']]
657 fksleg['color'] = part.get_color()
658 fksleg['charge'] = part.get_charge()
659 fksleg['massless'] = part['mass'].lower() == 'zero'
660 fksleg['spin'] = part.get('spin')
661 fksleg['is_part'] = part.get('is_part')
662 fksleg['self_antipart'] = part.get('self_antipart')
663 return fksleg
664
667 """given leglist, sets color and massless entries according to the model
668 variable.
669 return a FKSLeglist"""
670 fkslegs = FKSLegList()
671 for leg in leglist:
672 fkslegs.append(to_fks_leg(leg, model))
673 return fkslegs
674
677 """list of FKSLegs"""
678
680 """Test if object obj is a valid FKSLeg for the list."""
681 return isinstance(obj, FKSLeg)
682
683 - def sort(self,pert='QCD'):
684 """Sorting routine, sorting chosen to be optimal for madfks"""
685 sorted_leglist = FKSLegList()
686
687 initial_legs = FKSLegList([l for l in copy.copy(self) if not l['state']])
688
689 final_legs = FKSLegList([l for l in copy.copy(self) if l['state']])
690 if len(initial_legs) == 1:
691 sorted_leglist.extend(initial_legs)
692 elif len(initial_legs) == 2:
693 if initial_legs[0]['number'] > initial_legs[1]['number']:
694 initial_legs.reverse()
695 sorted_leglist.extend(initial_legs)
696 else:
697 raise FKSProcessError('Too many initial legs')
698
699 if pert == 'QCD':
700 color = 'color'
701 zero = 1
702 elif pert == 'QED':
703 color = 'charge'
704 zero = 0.
705 else:
706 raise FKSProcessError,"Only QCD and QED is allowed not %s"% pert
707 colors = sorted(set([abs(l[color]) for l in final_legs]))
708
709 if zero in colors:
710 sorted_leglist.extend(sorted(\
711 [l for l in final_legs if l[color] == zero], key = itemgetter('number')))
712 colors.remove(zero)
713
714
715 massless_dict = {}
716 massive_dict = {}
717 for col in colors:
718 col_legs = FKSLegList([l for l in final_legs if abs(l[color]) == col])
719
720 massive_dict[col] = [l for l in col_legs if not l['massless']]
721 massless_dict[col] = [l for l in col_legs if l['massless']]
722
723 for i_m, dict in enumerate([massive_dict, massless_dict]):
724 for col in colors:
725
726
727 if col == zero:
728 keys = [itemgetter('number'), itemgetter('number')]
729 reversing = False
730 else:
731 keys = [itemgetter('id'), itemgetter('id')]
732 reversing = True
733
734 init_pdg_legs = []
735 list = dict[col]
736 if len(initial_legs) == 2:
737
738 for i in range(len(set([ abs(l['id']) for l in initial_legs]))):
739 pdg = abs(initial_legs[i]['id'])
740 init_pdg_legs = [l for l in list if abs(l['id']) == pdg]
741 if init_pdg_legs:
742
743
744 init_pdg_legs.sort(key = keys[i_m], reverse=reversing)
745 sorted_leglist.extend(FKSLegList(init_pdg_legs))
746
747 init_pdgs = [ abs(l['id']) for l in initial_legs]
748 other_legs = [l for l in list if not abs(l['id']) in init_pdgs]
749 other_legs.sort(key = keys[i_m], reverse=reversing)
750 sorted_leglist.extend(FKSLegList(other_legs))
751 else:
752 list.sort(key = keys[i_m], reverse=reversing)
753 sorted_leglist.extend(FKSLegList(list))
754
755 for i, l in enumerate(sorted_leglist):
756 self[i] = l
757
761 """a class for FKS legs: it inherits from the ususal leg class, with two
762 extra keys in the dictionary:
763 -'fks', whose value can be 'i', 'j' or 'n' (for "normal" particles)
764 -'color', which gives the color of the leg
765 -'charge', which gives the charge of the leg
766 -'massless', boolean, true if leg is massless
767 -'spin' which gives the spin of leg
768 -'is_part', boolean, true if leg is an particle
769 -'self_antipart', boolean, true if leg is an self-conjugated particle
770 """
771
773 """Default values for all properties"""
774 super(FKSLeg, self).default_setup()
775
776 self['fks'] = 'n'
777 self['color'] = 0
778 self['charge'] = 0.
779 self['massless'] = True
780 self['spin'] = 0
781 self['is_part'] = True
782 self['self_antipart'] = False
783
785 """Return particle property names as a nicely sorted list."""
786 keys = super(FKSLeg, self).get_sorted_keys()
787 keys += ['fks', 'color','charge', 'massless', 'spin','is_part','self_antipart']
788 return keys
789
790
791 - def filter(self, name, value):
792 """Filter for valid leg property values."""
793
794 if name == 'fks':
795 if not isinstance(value, str):
796 raise self.PhysicsObjectError, \
797 "%s is not a valid string for leg fks flag" \
798 % str(value)
799 if name in ['color', 'spin']:
800 if not isinstance(value, int):
801 raise self.PhysicsObjectError, \
802 "%s is not a valid leg %s flag" % \
803 str(value),name
804
805 if name in ['massless','self_antipart','is_part']:
806 if not isinstance(value, bool):
807 raise self.PhysicsObjectError, \
808 "%s is not a valid boolean for leg flag %s" % \
809 str(value),name
810 if name is 'charge':
811 if not isinstance(value, float):
812 raise self.PhysicsObjectError, \
813 "%s is not a valid float for leg flag charge" \
814 % str(value)
815 return super(FKSLeg,self).filter(name, value)
816