def test_find_symmetry_decay_chain_with_subprocess_group(self): """Test the find_symmetry function for subprocess groups""" procs = [[2, -1, 24, 21, 21], [-3, 4, 24, 21, 21]] decays = [[24, -11, 12], [24, -13, 14]] amplitudes = diagram_generation.AmplitudeList() decay_amps = diagram_generation.DecayChainAmplitudeList() for proc, decay in zip(procs, decays): # Define the multiprocess my_leglist = base_objects.LegList([\ base_objects.Leg({'id': id, 'state': True}) for id in proc]) my_leglist[0].set('state', False) my_leglist[1].set('state', False) my_decaylegs = base_objects.LegList([\ base_objects.Leg({'id': id, 'state': True}) for id in decay]) my_decaylegs[0].set('state', False) my_process = base_objects.Process({ 'legs': my_leglist, 'model': self.base_model }) my_decay_proc = base_objects.Process({ 'legs': my_decaylegs, 'model': self.base_model, 'is_decay_chain': True }) my_amplitude = diagram_generation.Amplitude(my_process) my_decay = diagram_generation.DecayChainAmplitude(my_decay_proc) amplitudes.append(my_amplitude) decay_amps.append(my_decay) amplitudes = diagram_generation.DecayChainAmplitudeList([\ diagram_generation.DecayChainAmplitude({\ 'amplitudes': amplitudes, 'decay_chains': decay_amps})]) subproc_groups = \ group_subprocs.DecayChainSubProcessGroup.group_amplitudes(\ amplitudes,"madevent").generate_helas_decay_chain_subproc_groups() self.assertEqual(len(subproc_groups), 1) subproc_group = subproc_groups[0] self.assertEqual(len(subproc_group.get('matrix_elements')), 2) symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(\ subproc_group) self.assertEqual(len([s for s in symmetry if s > 0]), 5) self.assertEqual(symmetry, [1, -1, 1, 1, 1, -4, -5, 1])
def default_setup(self): """Define object and give default values""" self['core_groups'] = SubProcessGroupList() self['decay_groups'] = DecayChainSubProcessGroupList() # decay_chain_amplitudes is the original DecayChainAmplitudeList self['decay_chain_amplitudes'] = diagram_generation.DecayChainAmplitudeList()
def group_amplitudes(decay_chain_amps, criteria='madevent', matrix_elements_opts={}): """Recursive function. Starting from a DecayChainAmplitude, return a DecayChainSubProcessGroup with the core amplitudes and decay chains divided into subprocess groups""" assert isinstance(decay_chain_amps, diagram_generation.DecayChainAmplitudeList), \ "Argument to group_amplitudes must be DecayChainAmplitudeList" if criteria in ['matrix', 'standalone','pythia8','standalone_cpp', False]: criteria = 'madevent' assert criteria in ['madevent', 'madweight'] # Collect all amplitudes amplitudes = diagram_generation.AmplitudeList() for amp in decay_chain_amps: amplitudes.extend(amp.get('amplitudes')) # Determine core process groups core_groups = SubProcessGroup.group_amplitudes(amplitudes, criteria) dc_subproc_group = DecayChainSubProcessGroup(\ {'core_groups': core_groups, 'decay_chain_amplitudes': decay_chain_amps}) decays = diagram_generation.DecayChainAmplitudeList() # Recursively determine decay chain groups for decay_chain_amp in decay_chain_amps: decays.extend(decay_chain_amp.get('decay_chains')) if decays: dc_subproc_group.get('decay_groups').append(\ DecayChainSubProcessGroup.group_amplitudes(decays, criteria)) return dc_subproc_group
def test_find_symmetry_gg_tt_fullylept(self): """Test the find_symmetry function for subprocess groups""" procs = [[21,21, 6, -6]] decayt = [[6,5,-11,12],[6, 5,-13, 14]] decaytx = [[-6,-5,11,-12],[-6, -5, 13,-14]] amplitudes = diagram_generation.AmplitudeList() decay_amps = diagram_generation.DecayChainAmplitudeList() proc = procs[0] my_leglist = base_objects.LegList([\ base_objects.Leg({'id': id, 'state': True}) for id in proc]) my_leglist[0].set('state', False) my_leglist[1].set('state', False) my_process = base_objects.Process({'legs':my_leglist, 'model':self.base_model}) my_amplitude = diagram_generation.Amplitude(my_process) amplitudes.append(my_amplitude) for dect in decayt: my_top_decaylegs = base_objects.LegList([\ base_objects.Leg({'id': id, 'state': True}) for id in dect]) my_top_decaylegs[0].set('state', False) my_decayt_proc = base_objects.Process({'legs':my_top_decaylegs, 'model':self.base_model, 'is_decay_chain': True}) my_decayt = diagram_generation.DecayChainAmplitude(my_decayt_proc) decay_amps.append(my_decayt) for dectx in decaytx: # Define the multiprocess my_topx_decaylegs = base_objects.LegList([\ base_objects.Leg({'id': id, 'state': True}) for id in dectx]) my_topx_decaylegs[0].set('state', False) my_decaytx_proc = base_objects.Process({'legs':my_topx_decaylegs, 'model':self.base_model, 'is_decay_chain': True}) my_decaytx = diagram_generation.DecayChainAmplitude(my_decaytx_proc) decay_amps.append(my_decaytx) amplitudes = diagram_generation.DecayChainAmplitudeList([\ diagram_generation.DecayChainAmplitude({\ 'amplitudes': amplitudes, 'decay_chains': decay_amps})]) subproc_groups = \ group_subprocs.DecayChainSubProcessGroup.group_amplitudes(\ amplitudes).generate_helas_decay_chain_subproc_groups() self.assertEqual(len(subproc_groups), 1) subproc_group = subproc_groups[0] self.assertEqual(len(subproc_group.get('matrix_elements')), 1) symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(\ subproc_group) sol_perms = [list(range(8)), list(range(8)), [0,1,5,6,7,2,3,4]] self.assertEqual(len([s for s in symmetry if s > 0]), 2) self.assertEqual(symmetry, [1, 1, -2]) self.assertEqual(perms, sol_perms)
def test_ungrouping_lepton(self): """check that the routines which ungroup the process for the muon/electron processes works as expected""" # Setup A simple model mypartlist = base_objects.ParticleList() myinterlist = base_objects.InteractionList() # A quark U and its antiparticle mypartlist.append( base_objects.Particle({ 'name': 'u', 'antiname': 'u~', 'spin': 2, 'color': 3, 'mass': 'zero', 'width': 'zero', 'texname': 'u', 'antitexname': '\bar u', 'line': 'straight', 'charge': 2. / 3., 'pdg_code': 2, 'propagating': True, 'is_part': True, 'self_antipart': False })) u = mypartlist[-1] antiu = copy.copy(u) antiu.set('is_part', False) # A quark D and its antiparticle mypartlist.append( base_objects.Particle({ 'name': 'd', 'antiname': 'd~', 'spin': 2, 'color': 3, 'mass': 'zero', 'width': 'zero', 'texname': 'd', 'antitexname': '\bar d', 'line': 'straight', 'charge': -1. / 3., 'pdg_code': 1, 'propagating': True, 'is_part': True, 'self_antipart': False })) d = mypartlist[-1] antid = copy.copy(d) antid.set('is_part', False) # A quark C and its antiparticle mypartlist.append( base_objects.Particle({ 'name': 'c', 'antiname': 'c~', 'spin': 2, 'color': 3, 'mass': 'zero', 'width': 'zero', 'texname': 'u', 'antitexname': '\bar u', 'line': 'straight', 'charge': 2. / 3., 'pdg_code': 4, 'propagating': True, 'is_part': True, 'self_antipart': False })) c = mypartlist[-1] antic = copy.copy(c) antic.set('is_part', False) # electron/positront mypartlist.append( base_objects.Particle({ 'name': 'e-', 'antiname': 'e+', 'spin': 2, 'color': 1, 'mass': 'zero', 'width': 'zero', 'texname': 'u', 'antitexname': '\bar u', 'line': 'straight', 'charge': 1, 'pdg_code': 11, 'propagating': True, 'is_part': True, 'self_antipart': False })) e = mypartlist[-1] antie = copy.copy(e) mu = copy.copy(e) antie.set('is_part', False) mu.set('name', 'mu-') mu.set('antiname', 'mu+') mu.set('pdg_code', 13) mypartlist.append(mu) antimu = copy.copy(mu) antimu.set('is_part', False) # A Z mypartlist.append( base_objects.Particle({ 'name': 'z', 'antiname': 'z', 'spin': 3, 'color': 1, 'mass': 'MZ', 'width': 'WZ', 'texname': 'Z', 'antitexname': 'Z', 'line': 'wavy', 'charge': 0., 'pdg_code': 23, 'propagating': True, 'is_part': True, 'self_antipart': True })) z = mypartlist[-1] # Coupling of Z to quarks myinterlist.append(base_objects.Interaction({ 'id': 1, 'particles': base_objects.ParticleList(\ [antiu, \ u, \ z]), 'color': [color.ColorString([color.T(1,0)])], 'lorentz':['FFV1', 'FFV2'], 'couplings':{(0, 0):'GUZ1', (0, 1):'GUZ2'}, 'orders':{'QED':1}})) myinterlist.append(base_objects.Interaction({ 'id': 2, 'particles': base_objects.ParticleList(\ [antid, \ d, \ z]), 'color': [color.ColorString([color.T(1,0)])], 'lorentz':['FFV1', 'FFV2'], 'couplings':{(0, 0):'GDZ1', (0, 1):'GDZ2'}, 'orders':{'QED':1}})) myinterlist.append(base_objects.Interaction({ 'id': 3, 'particles': base_objects.ParticleList(\ [antic, \ c, \ z]), 'color': [color.ColorString([color.T(1,0)])], 'lorentz':['FFV1', 'FFV2'], 'couplings':{(0, 0):'GUZ1', (0, 1):'GUZ2'}, 'orders':{'QED':1}})) # Coupling of Z to leptons myinterlist.append(base_objects.Interaction({ 'id': 4, 'particles': base_objects.ParticleList(\ [antie, \ e, \ z]), 'color': [color.ColorString()], 'lorentz':['FFV1', 'FFV2'], 'couplings':{(0, 0):'GLZ1', (0, 1):'GLZ2'}, 'orders':{'QED':1}})) # Coupling of Z to leptons myinterlist.append(base_objects.Interaction({ 'id': 5, 'particles': base_objects.ParticleList(\ [antimu, \ mu, \ z]), 'color': [color.ColorString()], 'lorentz':['FFV1', 'FFV2'], 'couplings':{(0, 0):'GLZ1', (0, 1):'GLZ2'}, 'orders':{'QED':1}})) mymodel = base_objects.Model() mymodel.set('particles', mypartlist) mymodel.set('interactions', myinterlist) mymodel.set('name', 'sm') procs = [[1, -1, 23], [2, -2, 23], [4, -4, 23]] decays = [[23, 11, -11], [23, 13, -13]] coreamplitudes = diagram_generation.AmplitudeList() decayamplitudes = diagram_generation.AmplitudeList() decayprocs = base_objects.ProcessList() #Building the basic objects for proc in procs: # Define the multiprocess my_leglist = base_objects.LegList([\ base_objects.Leg({'id': id, 'state': True}) for id in proc]) my_leglist[0].set('state', False) my_leglist[1].set('state', False) my_process = base_objects.Process({ 'legs': my_leglist, 'model': mymodel }) my_amplitude = diagram_generation.Amplitude(my_process) my_amplitude.set('has_mirror_process', True) coreamplitudes.append(my_amplitude) for proc in decays: # Define the multiprocess my_leglist = base_objects.LegList([\ base_objects.Leg({'id': id, 'state': True}) for id in proc]) my_leglist[0].set('state', False) my_process = base_objects.Process({ 'legs': my_leglist, 'model': mymodel, 'is_decay_chain': True }) my_amplitude = diagram_generation.Amplitude(my_process) decayamplitudes.append(my_amplitude) decayprocs.append(my_process) decays = diagram_generation.DecayChainAmplitudeList([\ diagram_generation.DecayChainAmplitude({\ 'amplitudes': decayamplitudes})]) decay_chains = diagram_generation.DecayChainAmplitude({\ 'amplitudes': coreamplitudes, 'decay_chains': decays}) dc_subproc_group = group_subprocs.DecayChainSubProcessGroup.\ group_amplitudes(\ diagram_generation.DecayChainAmplitudeList([decay_chains])) subproc_groups = \ dc_subproc_group.generate_helas_decay_chain_subproc_groups() ###################### ## Make the test!! ## ###################### self.assertEqual(len(subproc_groups), 1) subproc_groups = subproc_groups.split_lepton_grouping() self.assertEqual(len(subproc_groups), 2) # check that indeed for group in subproc_groups: self.assertEqual(len(group['matrix_elements']), 2) has_muon = any( abs(l['id']) == 13 for l in group['matrix_elements'][0] ['processes'][0]['decay_chains'][0]['legs']) for me in group['matrix_elements']: if abs(me['processes'][0]['legs'][0]['id']) == 1: self.assertEqual(len(me['processes']), 1) else: self.assertEqual(len(me['processes']), 2) for proc in me['processes']: for dec in proc['decay_chains']: if has_muon: self.assertFalse( any(abs(l['id']) == 11 for l in dec['legs'])) else: self.assertFalse( any(abs(l['id']) == 13 for l in dec['legs'])) self.assertNotEqual(group['name'], 'qq_z_z_ll') if has_muon: self.assertEqual(group['name'], 'qq_z_z_mummup') else: self.assertEqual(group['name'], 'qq_z_z_emep') group['name']