Package madgraph :: Package fks :: Module fks_common
[hide private]
[frames] | no frames]

Source Code for Module madgraph.fks.fks_common

  1  ################################################################################ 
  2  # 
  3  # Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors 
  4  # 
  5  # This file is a part of the MadGraph5_aMC@NLO project, an application which  
  6  # automatically generates Feynman diagrams and matrix elements for arbitrary 
  7  # high-energy processes in the Standard Model and beyond. 
  8  # 
  9  # It is subject to the MadGraph5_aMC@NLO license which should accompany this  
 10  # distribution. 
 11  # 
 12  # For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch 
 13  # 
 14  ################################################################################ 
 15   
 16  """Definitions of the objects needed both for MadFKS from real  
 17  and MadFKS from born""" 
 18   
 19  from __future__ import absolute_import 
 20  from __future__ import print_function 
 21  import madgraph.core.base_objects as MG 
 22  import madgraph.core.helas_objects as helas_objects 
 23  import madgraph.core.diagram_generation as diagram_generation 
 24  import madgraph.core.color_amp as color_amp 
 25  import madgraph.core.color_algebra as color_algebra 
 26  import madgraph.various.misc as misc 
 27  from operator import itemgetter 
 28  import copy 
 29  import logging 
 30  import array 
 31  import fractions 
 32  import six 
 33  from six.moves import range 
34 35 36 37 -class FKSProcessError(Exception):
38 """Exception for MadFKS""" 39 pass
40
41 42 -class FKSDiagramTag(diagram_generation.DiagramTag): #test written
43 """Modified diagram tags to be used to link born and real configurations. 44 """ 45 46 @staticmethod 53 225
226 227 228 -def find_orders(amp): #test_written
229 """Takes an amplitude as input, and returns a dictionary with the 230 orders of the couplings. 231 """ 232 assert isinstance(amp, diagram_generation.Amplitude) 233 orders = {} 234 for diag in amp.get('diagrams'): 235 for order, value in diag.get('orders').items(): 236 if value != 0 or order in list(amp['process']['orders'].keys()): 237 try: 238 orders[order] = max(orders[order], value) 239 except KeyError: 240 orders[order] = value 241 return orders 242
243 244 -def find_splittings(leg, model, dict, pert='QCD'): #test written
245 """Finds the possible splittings corresponding to leg 246 """ 247 if dict == {}: 248 dict = find_pert_particles_interactions(model, pert) 249 splittings = [] 250 #check that the leg is a qcd leg 251 252 if leg.get('id') in dict['pert_particles']: 253 part = model.get('particle_dict')[leg.get('id')] 254 antipart = model.get('particle_dict')[part.get_anti_pdg_code()] 255 for ii in dict['interactions']: 256 #check which interactions contain leg and at least one soft particles: 257 parts = copy.deepcopy(ii['particles']) 258 nsoft = 0 259 if part in parts: 260 #pops the ANTI-particle of part from the interaction 261 parts.pop(parts.index(antipart)) 262 for p in parts: 263 if p.get_pdg_code() in dict['soft_particles']: 264 nsoft += 1 265 if nsoft >= 1: 266 splittings.extend(split_leg(leg, parts, model)) 267 return splittings 268
269 270 -def split_leg(leg, parts, model): #test written
271 """Splits the leg into parts, and returns the two new legs. 272 """ 273 #for an outgoing leg take the antiparticles 274 split = [] 275 #for a final state particle one can have only a splitting 276 if leg['state'] : 277 split.append([]) 278 for part in parts: 279 split[-1].append(to_fks_leg({'state': True, \ 280 'id': part.get_pdg_code()},model)) 281 ij_final(split[-1]) 282 #while for an initial state particle one can have two splittings 283 # if the two partons are different 284 else: 285 if parts[0] != parts[1]: 286 for part in parts: 287 cparts = copy.deepcopy(parts) 288 split.append([\ 289 to_fks_leg({'state': False, 290 'id': cparts.pop(cparts.index(part)).get_pdg_code(), 291 'fks': 'j'}, model), 292 to_fks_leg({'state': True, 293 'id': cparts[0].get_anti_pdg_code(), 294 'fks': 'i'}, model)\ 295 ]) 296 else: 297 split.append([\ 298 to_fks_leg({'state': False, 299 'id': parts[0].get_pdg_code(), 300 'fks': 'j'}, model), 301 to_fks_leg({'state': True, 302 'id': parts[1].get_anti_pdg_code(), 303 'fks': 'i'}, model)]) 304 return split 305
306 307 -def ij_final(pair):
308 """given a pair of legs in the final state, assigns the i/j fks id 309 NOTE: the j partons is always put before the i one 310 """ 311 #if a massless bosonic particle is in the pair, it is i 312 #else by convention the anti-particle is labeled i 313 #the order of the splitting is [ j, i] 314 if len(pair) == 2: 315 for i in range(len(pair)): 316 set = 0 317 if (pair[i]['massless'] and pair[i]['self_antipart']) or \ 318 (not pair[i]['is_part'] and pair[1-i]['is_part'] and\ 319 (pair[i]['spin']+pair[1-i]['spin'])%2==0) and not set: 320 pair[i]['fks'] = 'i' 321 pair[1-i]['fks'] = 'j' 322 #check that first j then i 323 if i < 1 - i: 324 pair.reverse() 325 set = 1
326
327 -def insert_legs(leglist_orig, leg, split,pert='QCD'):
328 """Returns a new leglist with leg splitted into split. 329 The convention is to remove leg ij, replace it with leg j, and put 330 i at the end of the group of legs with the same color(charge) representation 331 """ 332 if pert =='QCD': 333 color = 'color' 334 elif pert == 'QED': 335 color = 'charge' 336 else: 337 raise FKSProcessError("Only QCD or QED is allowed not %s" % pert) 338 # the deepcopy statement is crucial 339 leglist = FKSLegList(copy.deepcopy(leglist_orig)) 340 #find the position of the first final state leg 341 for i in range(len(leglist)): 342 if leglist[-i - 1].get('state'): 343 firstfinal = len(leglist) - i - 1 344 # replace leg with leg_j (split[0]) 345 leglist[leglist.index(leg)] = split[0] 346 # and find where to insert i (split[1]) 347 col_maxindex = {} 348 mass_col_maxindex = {} 349 for col in set([l[color] for l in leglist[firstfinal:] if l['massless']]): 350 col_maxindex[col] = max([0] + [leglist.index(l) for l in leglist[firstfinal:]\ 351 if l[color] == col and l['massless']]) 352 for col in set([abs(l[color]) for l in leglist[firstfinal:] if not l['massless']]): 353 mass_col_maxindex[col] = max([0] + [leglist.index(l) for l in leglist[firstfinal:]\ 354 if abs(l[color]) == col and not l['massless']]) 355 #no need to keep info on particles with color > i 356 if pert == 'QCD': 357 for col in copy.copy(list(col_maxindex.keys())): 358 if abs(col) > abs(split[1][color]): 359 del col_maxindex[col] 360 ### for col in copy.copy(mass_col_maxindex.keys()): 361 ### if abs(col) > abs(split[1][color]): 362 ### del mass_col_maxindex[col] 363 #also remove antiquarks if i is a quark or a fermion 364 if split[1]['is_part'] and not split[1]['self_antipart']: 365 # In old MADFKS5, the line below was used instead. It is however equivalent in principle. 366 # We can remove this comment and the line below altogether after validation and complete 367 # merge of the EW branch in aMC@NLO trunk. 368 #if split[1][color] > 0: 369 try: 370 del col_maxindex[-split[1][color]] 371 except KeyError: 372 pass 373 #so now the maximum of the max_col entries should be the position to insert leg i 374 leglist.insert(max(list(col_maxindex.values()) + list(mass_col_maxindex.values()) + [firstfinal - 1] ) + 1, split[1]) 375 ### leglist.insert(max(col_maxindex.values() + [firstfinal - 1] ) + 1, split[1]) 376 # for sleg in split: 377 # leglist.insert(i, sleg) 378 # #keep track of the number for initial state legs 379 # #if not sleg.get('state') and not leg.get('state'): 380 # leglist[i]['number'] = leg['number'] 381 # i += 1 382 # if i < firstfinal: 383 # i = firstfinal 384 # 385 # leglist.sort() 386 for i, leg in enumerate(leglist): 387 leg['number'] = i + 1 388 return leglist
389
390 391 -def combine_ij( i, j, model, dict, pert='QCD'): #test written
392 """checks whether FKSlegs i and j can be combined together in the given model 393 and with given perturbation order and if so combines them into ij. 394 If dict is empty it is initialized with find_pert_particles_interactions 395 """ 396 if dict == {}: 397 dict = find_pert_particles_interactions(model, pert) 398 ij = [] 399 num = copy.copy(min(i.get('number'), j.get('number'))) 400 401 # we do not want j being a massless vector unless also i is or j is initial 402 not_double_counting = (j.get('spin') == 3 and j.get('massless') and 403 i.get('spin') == 3 and i.get('massless')) or \ 404 j.get('spin') != 3 or not j.get('massless') or \ 405 not j.get('state') 406 407 #if i and j are a final state particle and antiparticle pair, 408 # then we want i to be antipart and j to be 409 if j.get('state') and j.get('id') == - i.get('id'): 410 not_double_counting = not_double_counting and j.get('id') >0 411 412 if i.get('id') in dict['soft_particles'] and \ 413 j.get('id') in dict['pert_particles'] and \ 414 i.get('state') and not_double_counting: 415 for int in dict['interactions']: 416 parts= copy.copy(int['particles']) 417 #remove i 418 try: 419 parts.remove(model.get('particle_dict')[i.get('id')]) 420 except ValueError: 421 continue 422 423 #remove j if final state, anti j if initial state 424 if j.get('state'): 425 j_id = j.get('id') 426 else: 427 j_id = model.get('particle_dict')[j.get('id')].get_anti_pdg_code() 428 try: 429 parts.remove(model.get('particle_dict')[j_id]) 430 except ValueError: 431 continue 432 433 #ij is what remains if j is initial, the anti of if j is final 434 if j.get('state'): 435 ij.append(MG.Leg({ 436 'id': parts[0].get_anti_pdg_code(), 437 'state': True, 438 'number': num})) 439 else: 440 ij.append(MG.Leg({ 441 'id': parts[0].get_pdg_code(), 442 'state': False, 443 'number': num})) 444 return to_fks_legs(ij, model) 445
446 447 -def find_pert_particles_interactions(model, pert_order = 'QCD'): #test written
448 """given a model and pert_order, returns a dictionary with as entries: 449 --interactions : the interactions of order pert_order 450 --pert_particles : pdgs of particles taking part to interactions 451 --soft_particles : pdgs of massless particles in pert_particles 452 """ 453 #ghost_list = [82, -82] # make sure ghost_list is non-empty 454 ghost_list = [] 455 ghost_list += [ p.get_pdg_code() for p in model.get('particles') if p.get('ghost')] 456 qcd_inter = MG.InteractionList() 457 pert_parts = [] 458 soft_parts = [] 459 for i, ii in model.get('interaction_dict').items(): 460 # i want interections of pert_order: 1 (from LO to NLO), 461 # without any other orders 462 # and of "base" type 463 if ii.get('type') != 'base': continue 464 465 if ii.get('orders') == {pert_order:1} and len(ii['particles']) == 3 : 466 masslist = [p.get('mass').lower() for p in ii['particles']] 467 468 # require that at least one particle be soft and of even spin for the interaction to be IR singular 469 found_soft_even_spin_particle = False 470 for p in ii['particles']: 471 if p.get('mass').lower()=='zero': 472 if p.get('spin')%2==1: 473 found_soft_even_spin_particle = True 474 break 475 if not found_soft_even_spin_particle: 476 continue 477 478 # check that there is at least a massless particle, and that the 479 # remaining ones have the same mass 480 # (otherwise the real emission final state will not be degenerate 481 # with the born one 482 try: 483 masslist.remove('zero') 484 except ValueError: 485 continue 486 if len(set(masslist)) == 1 and not \ 487 any( [ p.get_pdg_code() in ghost_list for p in ii['particles']]) : 488 qcd_inter.append(ii) 489 for pp in ii['particles']: 490 pert_parts.append(pp.get_pdg_code()) 491 if pp['mass'].lower() == 'zero': 492 soft_parts.append(pp.get_pdg_code()) 493 494 return {'interactions': sorted(qcd_inter, key=misc.cmp_to_key(misc.dict_cmp)), 495 'pert_particles': sorted(set(pert_parts)), 496 'soft_particles': sorted(set(soft_parts))} 497 500 """insert the color links in col_obj: returns a list of dictionaries 501 (one for each link) with the following entries: 502 --link: the numbers of the linked legs 503 --link_basis: the linked color basis 504 --link_matrix: the color matrix created from the original basis and the linked one 505 """ 506 assert isinstance(col_basis, color_amp.ColorBasis) 507 assert isinstance(col_obj, list) 508 result =[] 509 for link in links: 510 this = {} 511 #define the link 512 l =[] 513 for leg in link['legs']: 514 l.append(leg.get('number')) 515 this['link'] = l 516 517 #replace the indices in col_obj of the linked legs according to 518 # link['replacements'] 519 # and extend-> product the color strings 520 521 this_col_obj = [] 522 for old_dict in col_obj: 523 new_dict = dict(old_dict) 524 for k, string in new_dict.items(): 525 new_dict[k] = string.create_copy() 526 for col in new_dict[k]: 527 for ind in col: 528 for pair in link['replacements']: 529 if ind == pair[0]: 530 col[col.index(ind)] = pair[1] 531 new_dict[k].product(link['string']) 532 this_col_obj.append(new_dict) 533 basis_link = color_amp.ColorBasis() 534 for ind, new_dict in enumerate(this_col_obj): 535 basis_link.update_color_basis(new_dict, ind) 536 537 this['link_basis'] = basis_link 538 this['link_matrix'] = color_amp.ColorMatrix(col_basis,basis_link) 539 result.append(this) 540 basis_orig = color_amp.ColorBasis() 541 for ind, new_dict in enumerate(col_obj): 542 basis_orig.update_color_basis(new_dict, ind) 543 544 for link in result: 545 link['orig_basis'] = basis_orig 546 return result 547 551 """Finds all the possible color(charge) links between any 552 two legs of the born. 553 If symm is true, only half of the color links are generated, those 554 for which leg1['number'] <= leg2['number'] 555 """ 556 if pert == 'QCD': 557 color = 'color' 558 zero = 1 559 elif pert == 'QED': 560 color = 'charge' 561 zero = 0. 562 else: 563 raise FKSProcessError("Only QCD or QED is allowed not %s" % pert) 564 color_links = [] 565 for leg1 in leglist: 566 for leg2 in leglist: 567 #legs must be colored(charged) and different, unless massive 568 if (leg1.get(color) != zero and leg2.get(color) != zero) \ 569 and (leg1 != leg2 or not leg1.get('massless')): 570 if not symm or leg1['number'] <= leg2['number']: 571 col_dict = legs_to_color_link_string(leg1,leg2,pert = pert) 572 color_links.append({ 573 'legs': [leg1, leg2], 574 'string': col_dict['string'], 575 'replacements': col_dict['replacements']}) 576 577 return color_links 578 581 """given two FKSlegs, returns a dictionary containing: 582 --string: the color link between the two particles, to be appended to 583 the old color string 584 extra minus or 1/2 factor are included as it was done in MadDipole 585 --replacements: a pair of lists containing the replacements of the color 586 indices in the old string to match the link 587 """ 588 #the second-to-last index of the t is the triplet, 589 # the last is the anti-triplet 590 591 legs = FKSLegList([leg1, leg2]) 592 dict = {} 593 min_index = -3000 594 iglu = min_index*2 595 string = color_algebra.ColorString() 596 replacements = [] 597 if pert == 'QCD': 598 if leg1 != leg2: 599 for leg in legs: 600 min_index -= 1 601 num = leg.get('number') 602 replacements.append([num, min_index]) 603 icol = 1 604 if not leg.get('state'): 605 icol = - 1 606 if leg.get('color') * icol == 3: 607 string.product(color_algebra.ColorString([ 608 color_algebra.T(iglu, num, min_index)])) 609 string.coeff = string.coeff * (-1) 610 elif leg.get('color') * icol == - 3: 611 string.product(color_algebra.ColorString([ 612 color_algebra.T(iglu, min_index, num)])) 613 elif leg.get('color') == 8: 614 string.product(color_algebra.ColorString(init_list = [ 615 color_algebra.f(min_index,iglu,num)], 616 is_imaginary =True)) 617 618 else: 619 icol = 1 620 if not leg1.get('state'): 621 icol = - 1 622 num = leg1.get('number') 623 replacements.append([num, min_index -1]) 624 if leg1.get('color') * icol == 3: 625 string = color_algebra.ColorString( 626 [color_algebra.T(iglu, iglu, num, min_index -1)]) 627 elif leg1.get('color') * icol == - 3: 628 string = color_algebra.ColorString( 629 [color_algebra.T(iglu, iglu, min_index-1, num)]) 630 elif leg1.get('color') == 8: 631 string = color_algebra.ColorString(init_list = [ 632 color_algebra.f(min_index-1,iglu,min_index)], 633 is_imaginary =True) 634 string.product(color_algebra.ColorString(init_list = [ 635 color_algebra.f(min_index,iglu,num)], 636 is_imaginary =True)) 637 string.coeff = string.coeff * fractions.Fraction(1, 2) 638 639 elif pert == 'QED': 640 for leg in legs: 641 # make it a fraction 642 string.coeff = string.coeff * fractions.Fraction(leg['charge']*3.)*\ 643 fractions.Fraction(1,3) 644 else: 645 raise FKSProcessError("Only QCD or QED is allowed not %s"% pert) 646 647 dict['replacements'] = replacements 648 dict['string'] = string 649 return dict 650
651 652 -def sort_proc(process,pert = 'QCD'):
653 """Given a process, this function returns the same process 654 but with sorted FKSLegs. 655 """ 656 leglist = to_fks_legs(process.get('legs'), process.get('model')) 657 leglist.sort(pert = pert) 658 for n, leg in enumerate(leglist): 659 leg['number'] = n + 1 660 process['legs'] = leglist 661 # add this line to pass ./test_managers.py -p A test_check_ppzjj 662 process['legs_with_decays']=MG.LegList() 663 664 return process
665
666 667 -def to_leg(fksleg):
668 """Given a FKSLeg, returns the original Leg. 669 """ 670 leg = MG.Leg( \ 671 {'id': fksleg.get('id'), 672 'number': fksleg.get('number'), 673 'state': fksleg.get('state'), 674 'from_group': fksleg.get('from_group'), 675 'polarization': fksleg.get('polarization') 676 }) 677 return leg
678
679 680 -def to_legs(fkslegs):
681 """Given a FKSLegList, returns the corresponding LegList. 682 """ 683 leglist = MG.LegList() 684 for leg in fkslegs: 685 leglist.append(to_leg(leg)) 686 return leglist
687
688 689 -def to_fks_leg(leg, model): #test written
690 """Given a leg or a dict with Leg entries, 691 adds color, spin and massless entries, according to model""" 692 fksleg = FKSLeg(leg) 693 part = model.get('particle_dict')[leg['id']] 694 fksleg['color'] = part.get_color() 695 fksleg['charge'] = part.get_charge() 696 fksleg['massless'] = part['mass'].lower() == 'zero' 697 fksleg['spin'] = part.get('spin') 698 fksleg['is_part'] = part.get('is_part') 699 fksleg['self_antipart'] = part.get('self_antipart') 700 return fksleg 701
702 703 -def to_fks_legs(leglist, model): #test written
704 """given leglist, sets color and massless entries according to the model 705 variable. 706 return a FKSLeglist""" 707 fkslegs = FKSLegList() 708 for leg in leglist: 709 fkslegs.append(to_fks_leg(leg, model)) 710 return fkslegs 711
712 713 -class FKSLegList(MG.LegList):
714 """list of FKSLegs""" 715
716 - def is_valid_element(self, obj):
717 """Test if object obj is a valid FKSLeg for the list.""" 718 return isinstance(obj, FKSLeg)
719
720 - def sort(self,pert='QCD'):
721 """Sorting routine, sorting chosen to be optimal for madfks""" 722 sorted_leglist = FKSLegList() 723 #find initial state legs 724 initial_legs = FKSLegList([l for l in copy.copy(self) if not l['state']]) 725 #find final state legs 726 final_legs = FKSLegList([l for l in copy.copy(self) if l['state']]) 727 if len(initial_legs) == 1: 728 sorted_leglist.extend(initial_legs) 729 elif len(initial_legs) == 2: 730 if initial_legs[0]['number'] > initial_legs[1]['number']: 731 initial_legs.reverse() 732 sorted_leglist.extend(initial_legs) 733 else: 734 raise FKSProcessError('Too many initial legs') 735 #find color representations 736 if pert == 'QCD': 737 color = 'color' 738 zero = 1 739 elif pert == 'QED': 740 color = 'charge' 741 zero = 0. 742 else: 743 raise FKSProcessError("Only QCD and QED is allowed not %s"% pert) 744 colors = sorted(set([abs(l[color]) for l in final_legs])) 745 # first put massless particles, without any rearrangment 746 if zero in colors: 747 sorted_leglist.extend(sorted(\ 748 [l for l in final_legs if l[color] == zero], key = itemgetter('number'))) 749 colors.remove(zero) 750 751 #now go for colored legs, put first all massive legs, then all massless legs 752 massless_dict = {} 753 massive_dict = {} 754 for col in colors: 755 col_legs = FKSLegList([l for l in final_legs if abs(l[color]) == col]) 756 #find massive and massless legs in this color repr 757 massive_dict[col] = [l for l in col_legs if not l['massless']] 758 massless_dict[col] = [l for l in col_legs if l['massless']] 759 760 for i_m, dict in enumerate([massive_dict, massless_dict]): 761 for col in colors: 762 # sorting may be different for massive and massless particles 763 # for color singlets, do not change order 764 if col == zero: 765 keys = [itemgetter('number'), itemgetter('number')] 766 reversing = False 767 else: 768 keys = [itemgetter('id'), itemgetter('id')] 769 reversing = True 770 771 init_pdg_legs = [] 772 list = dict[col] 773 if len(initial_legs) == 2: 774 #put first legs which have the same abs(pdg) of the initial ones 775 for i in range(len(set([ abs(l['id']) for l in initial_legs]))): 776 pdg = abs(initial_legs[i]['id']) 777 init_pdg_legs = [l for l in list if abs(l['id']) == pdg] 778 if init_pdg_legs: 779 # sort in order to put first quarks then antiparticles, 780 # and to put fks partons as n j i 781 init_pdg_legs.sort(key = keys[i_m], reverse=reversing) 782 sorted_leglist.extend(FKSLegList(init_pdg_legs)) 783 784 init_pdgs = [ abs(l['id']) for l in initial_legs] 785 other_legs = [l for l in list if not abs(l['id']) in init_pdgs] 786 other_legs.sort(key = keys[i_m], reverse=reversing) 787 sorted_leglist.extend(FKSLegList(other_legs)) 788 else: 789 list.sort(key = keys[i_m], reverse=reversing) 790 sorted_leglist.extend(FKSLegList(list)) 791 792 for i, l in enumerate(sorted_leglist): 793 self[i] = l
794
795 796 797 -class FKSLeg(MG.Leg):
798 """a class for FKS legs: it inherits from the ususal leg class, with two 799 extra keys in the dictionary: 800 -'fks', whose value can be 'i', 'j' or 'n' (for "normal" particles) 801 -'color', which gives the color of the leg 802 -'charge', which gives the charge of the leg 803 -'massless', boolean, true if leg is massless 804 -'spin' which gives the spin of leg 805 -'is_part', boolean, true if leg is an particle 806 -'self_antipart', boolean, true if leg is an self-conjugated particle 807 """ 808
809 - def default_setup(self):
810 """Default values for all properties""" 811 super(FKSLeg, self).default_setup() 812 813 self['fks'] = 'n' 814 self['color'] = 0 815 self['charge'] = 0. 816 self['massless'] = True 817 self['spin'] = 0 818 self['is_part'] = True 819 self['self_antipart'] = False
820
821 - def get_sorted_keys(self):
822 """Return particle property names as a nicely sorted list.""" 823 keys = super(FKSLeg, self).get_sorted_keys() 824 keys += ['fks', 'color','charge', 'massless', 'spin','is_part','self_antipart'] 825 return keys
826 827
828 - def filter(self, name, value):
829 """Filter for valid leg property values.""" 830 831 if name == 'fks': 832 if not isinstance(value, str): 833 raise self.PhysicsObjectError("%s is not a valid string for leg fks flag" \ 834 % str(value)) 835 if name in ['color', 'spin']: 836 if not isinstance(value, int): 837 six.reraise(self.PhysicsObjectError, "%s is not a valid leg %s flag" % \ 838 str(value), name) 839 840 if name in ['massless','self_antipart','is_part']: 841 if not isinstance(value, bool): 842 six.reraise(self.PhysicsObjectError, "%s is not a valid boolean for leg flag %s" % \ 843 str(value), name) 844 if name == 'charge': 845 if not isinstance(value, float): 846 raise self.PhysicsObjectError("%s is not a valid float for leg flag charge" \ 847 % str(value)) 848 return super(FKSLeg,self).filter(name, value)
849