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 addIOTestsForProcess(self, testName, testFolder, particles_ids, exporters, orders, files_to_check=IOTests.IOTest.all_files, perturbation_couplings=['QCD'], NLO_mode='virt', model=None, fortran_model=None): """ Simply adds a test for the process defined and all the exporters specified.""" if model == None: model = self.models['loop_sm'] if fortran_model == None: fortran_model = self.fortran_models['fortran_model'] needed = False if not isinstance(exporters, dict): if self.need(testFolder, testName): needed = True elif any(self.need('%s_%s'%(testFolder,exporter) ,testName) for \ exporter in exporters.keys()): needed = True if not needed: return myleglist = base_objects.LegList() for i, pid in enumerate(particles_ids): myleglist.append( base_objects.Leg({ 'id': pid, 'state': False if i < 2 else True })) myproc = base_objects.Process({ 'legs': myleglist, 'model': model, 'orders': orders, 'perturbation_couplings': perturbation_couplings, 'NLO_mode': NLO_mode }) # Exporter directly given if not isinstance(exporters, dict): test_list = [(testFolder, exporters)] # Several exporters given in a dictionary else: test_list = [('%s_%s'%(testFolder,exp),exporters[exp]) for exp in \ exporters.keys()] for (folderName, exporter) in test_list: if self.need(folderName, testName): self.addIOTest(folderName,testName, IOTests.IOTest(\ procdef=myproc, exporter=exporter, helasModel=fortran_model, testedFiles=files_to_check, outputPath=_proc_file_path))
def test_check_u_u_six_g(self): """Test the process u u > six g against literature expression""" myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id':2, 'state':False, 'number': 1})) myleglist.append(base_objects.Leg({'id':2, 'state':False, 'number': 2})) myleglist.append(base_objects.Leg({'id':9000006, 'state':True, 'number': 3})) myleglist.append(base_objects.Leg({'id':21, 'state':True, 'number': 4})) myproc = base_objects.Process({'legs':myleglist, 'model':self.base_model}) comparison_results, used_lorentz = \ process_checks.check_processes(myproc, quick=True) self.assertTrue(comparison_results[0]['passed'])
def test_uu_to_six_g(self): """Test the process u u > six g against literature expression""" myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id':2, 'state':False, 'number': 1})) myleglist.append(base_objects.Leg({'id':2, 'state':False, 'number': 2})) myleglist.append(base_objects.Leg({'id':9000006, 'state':True, 'number': 3})) myleglist.append(base_objects.Leg({'id':21, 'state':True, 'number': 4})) myproc = base_objects.Process({'legs':myleglist, 'model':self.base_model}) evaluator = process_checks.MatrixElementEvaluator(self.base_model, reuse = False) p, w_rambo = evaluator.get_momenta(myproc) amplitude = diagram_generation.Amplitude(myproc) matrix_element = helas_objects.HelasMatrixElement(amplitude) mg5_me_value, amp2 = evaluator.evaluate_matrix_element(matrix_element, p) comparison_value = uu_Dg(p, 6, evaluator.full_model) self.assertAlmostEqual(mg5_me_value, comparison_value, 12)
def def_diagrams_epemddx(self): """ Test the drawing of diagrams from the loop process e+e- > dd~ """ myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id': -11, 'state': False})) myleglist.append(base_objects.Leg({'id': 11, 'state': False})) myleglist.append(base_objects.Leg({'id': 1, 'state': True})) myleglist.append(base_objects.Leg({'id': -1, 'state': True})) myproc = base_objects.Process({ 'legs': myleglist, 'model': self.myloopmodel, 'orders': {}, 'perturbation_couplings': [ 'QCD', ], 'squared_orders': {} }) myloopamplitude = loop_diagram_generation.LoopAmplitude() myloopamplitude.set('process', myproc) myloopamplitude.generate_diagrams() # Now the drawing test on myloopamplitude['loop_diagrams'] return myloopamplitude['loop_diagrams']
def setUp(self): """load the model""" import madgraph.interface.master_interface as interface cmd = interface.MasterCmd() cmd.do_import('model sm') self.mybasemodel = cmd._curr_model self.mybasemodel.change_mass_to_complex_scheme() leg1 = base_objects.Leg({'id': 22, 'state': False}) leg2 = base_objects.Leg({'id': 24, 'state': False}) leg3 = base_objects.Leg({'id': 22, 'state': True}) leg4 = base_objects.Leg({'id': 24, 'state': True}) leg5 = base_objects.Leg({'id': 23, 'state': True}) legList1 = base_objects.LegList([leg1, leg2, leg3, leg4, leg5]) myproc = base_objects.Process({ 'legs': legList1, 'model': self.mybasemodel }) myamplitude = diagram_generation.Amplitude({'process': myproc}) self.mymatrixelement = helas_objects.HelasMatrixElement(myamplitude)
def test_find_symmetry_uu_tt_with_subprocess_group(self): """Test the find_symmetry function for subprocess groups""" procs = [[2,2,6,6]] amplitudes = diagram_generation.AmplitudeList() 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':self.base_model_4ferm}) my_amplitude = diagram_generation.Amplitude(my_process) amplitudes.append(my_amplitude) subproc_group = \ group_subprocs.SubProcessGroup.group_amplitudes(amplitudes, "madevent")[0] symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(\ subproc_group) self.assertEqual(len([s for s in symmetry if s > 0]), 1) self.assertEqual(symmetry, [1]) return
def test_colorize_uu_gg(self): """Test the colorize function for uu~ > gg""" myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id': -2, 'state': False})) myleglist.append(base_objects.Leg({'id': 2, 'state': False})) myleglist.extend([base_objects.Leg({'id': 21, 'state': True})] * 2) myprocess = base_objects.Process({ 'legs': myleglist, 'model': self.mymodel }) myamplitude = diagram_generation.Amplitude() myamplitude.set('process', myprocess) myamplitude.generate_diagrams() my_col_basis = color_amp.ColorBasis() # S channel col_dict = my_col_basis.colorize(myamplitude['diagrams'][0], self.mymodel) goal_dict = { (0, 0): color.ColorString([color.T(-1000, 1, 2), color.f(3, 4, -1000)]) } self.assertEqual(col_dict, goal_dict) # T channel col_dict = my_col_basis.colorize(myamplitude['diagrams'][1], self.mymodel) goal_dict = { (0, 0): color.ColorString([color.T(3, 1, -1000), color.T(4, -1000, 2)]) } self.assertEqual(col_dict, goal_dict) # U channel col_dict = my_col_basis.colorize(myamplitude['diagrams'][2], self.mymodel) goal_dict = { (0, 0): color.ColorString([color.T(4, 1, -1000), color.T(3, -1000, 2)]) } self.assertEqual(col_dict, goal_dict)
def test_find_symmetry_qq_qqg_with_subprocess_group(self): """Test the find_symmetry function for subprocess groups""" procs = [[2,-2,2,-2,21], [2,2,2,2,21]] amplitudes = diagram_generation.AmplitudeList() 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':self.base_model}) my_amplitude = diagram_generation.Amplitude(my_process) amplitudes.append(my_amplitude) subproc_group = \ group_subprocs.SubProcessGroup.group_amplitudes(amplitudes,"madevent")[0] symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(\ subproc_group) self.assertEqual(len([s for s in symmetry if s > 0]), 19) self.assertEqual(symmetry,[1, 1, 1, 1, -2, -3, -4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -8, -9, -10, -11, -12, -13, -14, -18, -19]) return # The test below doesn't apply with the new way of determining # config symmetry for subprocess groups, since we don't demand # that symmetric diagrams have identical particles. # Check that the momentum assignments work matrix_element = \ subproc_group.get('matrix_elements')[1] process = matrix_element.get('processes')[0] evaluator = process_checks.MatrixElementEvaluator(self.base_model, auth_skipping = True, reuse = True) p, w_rambo = evaluator.get_momenta(process) me_value, amp2_org = evaluator.evaluate_matrix_element(\ matrix_element, p) for isym, (sym, perm) in enumerate(zip(symmetry, perms)): new_p = [p[i] for i in perm] if sym >= 0: continue iamp = subproc_group.get('diagram_maps')[1].index(isym+1) isymamp = subproc_group.get('diagram_maps')[1].index(-sym) me_value, amp2 = evaluator.evaluate_matrix_element(\ matrix_element, new_p) self.assertAlmostEqual(amp2[iamp], amp2_org[isymamp])
def test_get_s_and_t_ub_tdg(self): """test that for the single-top (ub>tdg) the s-and t-channels are correctly returned""" myleglist = MG.LegList() myleglist.append(MG.Leg({'id': 2, 'state': False})) myleglist.append(MG.Leg({'id': 5, 'state': False})) myleglist.append(MG.Leg({'id': 6, 'state': True})) myleglist.append(MG.Leg({'id': 1, 'state': True})) myleglist.append(MG.Leg({'id': 21, 'state': True})) proc = MG.Process({ 'legs': myleglist, 'model': self.base_model, 'orders': { 'QCD': 1, 'QED': 2 } }) me = helas_objects.HelasMatrixElement( diagram_generation.Amplitude(proc)) #without flipping: s-and-t channel legs # note that leg 2 never appears target = [[[1, 4, -1], [-1, 3, -2], [-2, 5, -3]], [[5, 3, -1], [1, 4, -2], [-2, -1, -3]], [[1, 5, -1], [-1, 4, -2], [-2, 3, -3]], [[5, 4, -1], [1, -1, -2], [-2, 3, -3]]] #if we flip the s-and-t channel legs should be # note that leg 1 never appears target_flip = [[[2, 5, -1], [-1, 3, -2], [-2, 4, -3]], [[5, 3, -1], [2, -1, -2], [-2, 4, -3]], [[2, 3, -1], [-1, 4, -2], [-2, 5, -3]], [[5, 4, -1], [2, 3, -2], [-2, -1, -3]]] for id, diag in enumerate(me.get('diagrams')): s_ch, t_ch = diag.get('amplitudes')[0].get_s_and_t_channels( ninitial=2, model=self.base_model, new_pdg=7, reverse_t_ch=False) self.assertEqual( [ [l['number'] for l in v['legs']] for v in s_ch] + \ [ [l['number'] for l in v['legs']] for v in t_ch] , target[id]) for id, diag in enumerate(me.get('diagrams')): s_ch, t_ch = diag.get('amplitudes')[0].get_s_and_t_channels( ninitial=2, model=self.base_model, new_pdg=7, reverse_t_ch=True) self.assertEqual( [ [l['number'] for l in v['legs']] for v in s_ch] + \ [ [l['number'] for l in v['legs']] for v in t_ch] , target_flip[id])
def test_get_momenta(self): """Test the get_momenta function""" myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id':-11, 'state':False, 'number': 1})) myleglist.append(base_objects.Leg({'id':11, 'state':False, 'number': 2})) myleglist.append(base_objects.Leg({'id':22, 'state':True, 'number': 3})) myleglist.append(base_objects.Leg({'id':22, 'state':True, 'number': 4})) myleglist.append(base_objects.Leg({'id':23, 'state':True, 'number': 5})) myproc = base_objects.Process({'legs':myleglist, 'model':self.base_model}) evaluator = process_checks.MatrixElementEvaluator(self.base_model) full_model = evaluator.full_model p, w_rambo = evaluator.get_momenta(myproc) # Check massless external momenta for mom in p[:-1]: mass = mom[0]**2-(mom[1]**2+mom[2]**2+mom[3]**2) self.assertAlmostEqual(mass, 0., 8) mom = p[-1] mass = math.sqrt(mom[0]**2-(mom[1]**2+mom[2]**2+mom[3]**2)) self.assertAlmostEqual(mass, full_model.get('parameter_dict')['mdl_MZ'], 8) # Check momentum balance outgoing = [0]*4 incoming = [0]*4 for i in range(4): incoming[i] = sum([mom[i] for mom in p[:2]]) outgoing[i] = sum([mom[i] for mom in p[2:]]) self.assertAlmostEqual(incoming[i], outgoing[i], 8) # Check non-zero final state momenta for mom in p[2:]: for i in range(4): self.assertTrue(abs(mom[i]) > 0.)
def test_comparison_for_process(self): """Test check process for e+ e- > a Z""" myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id':-11, 'state':False})) myleglist.append(base_objects.Leg({'id':11, 'state':False})) myleglist.append(base_objects.Leg({'id':22, 'state':True})) myleglist.append(base_objects.Leg({'id':23, 'state':True})) myproc = base_objects.Process({'legs':myleglist, 'model':self.base_model}) process_checks.clean_added_globals(process_checks.ADDED_GLOBAL) comparison = process_checks.check_processes(myproc)[0][0] self.assertEqual(len(comparison['values']), 8) self.assertTrue(comparison['values'][0] > 0) self.assertTrue(comparison['passed']) comparison = process_checks.check_gauge(myproc) #check number of helicities/jamp nb_hel = [] nb_jamp = [] for one_comp in comparison: nb_hel.append(len(one_comp['value']['jamp'])) nb_jamp.append(len(one_comp['value']['jamp'][0])) self.assertEqual(nb_hel, [24]) self.assertEqual(nb_jamp, [1]) nb_fail = process_checks.output_gauge(comparison, output='fail') self.assertEqual(nb_fail, 0) comparison = process_checks.check_lorentz(myproc) #check number of helicities/jamp nb_hel = [] nb_jamp = [] for one_comp in comparison: nb_hel.append(len(one_comp['results'][0]['jamp'])) nb_jamp.append(len(one_comp['results'][0]['jamp'][0])) self.assertEqual(nb_hel, [24]) self.assertEqual(nb_jamp, [1]) nb_fail = process_checks.output_lorentz_inv(comparison, output='fail') self.assertEqual(0, nb_fail)
def test_find_symmetry_epem_aaa(self): """Test the find_symmetry function""" myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id':-11, 'state':False})) myleglist.append(base_objects.Leg({'id':11, 'state':False})) myleglist.append(base_objects.Leg({'id':22, 'state':True})) myleglist.append(base_objects.Leg({'id':22, 'state':True})) myleglist.append(base_objects.Leg({'id':22, 'state':True})) myproc = base_objects.Process({'legs':myleglist, 'model':self.base_model}) myamplitude = diagram_generation.Amplitude(myproc) matrix_element = helas_objects.HelasMatrixElement(myamplitude) symmetry, perms, ident_perms = diagram_symmetry.find_symmetry(matrix_element) self.assertEqual(symmetry, [6,-1,-1,-1,-1,-1]) # Check that the momentum assignments work process = matrix_element.get('processes')[0] evaluator = process_checks.MatrixElementEvaluator(self.base_model, auth_skipping = True, reuse = True) p, w_rambo = evaluator.get_momenta(process) me_value, amp2_org = evaluator.evaluate_matrix_element(\ matrix_element, p) for isym, (sym, perm) in enumerate(zip(symmetry, perms)): new_p = [p[i] for i in perm] if sym >= 0: continue me_value, amp2 = evaluator.evaluate_matrix_element(matrix_element, new_p) self.assertAlmostEqual(amp2[isym], amp2_org[-sym-1])
def test_rotate_momenta(self): """Test that matrix element and amp2 identical for rotated momenta""" myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id':2, 'state':False})) myleglist.append(base_objects.Leg({'id':-2, 'state':False})) myleglist.append(base_objects.Leg({'id':2, 'state':True})) myleglist.append(base_objects.Leg({'id':-2, 'state':True})) myleglist.append(base_objects.Leg({'id':21, 'state':True})) myproc = base_objects.Process({'legs':myleglist, 'model':self.base_model}) myamp = diagram_generation.Amplitude(myproc) matrix_element = helas_objects.HelasMatrixElement(myamp) evaluator = process_checks.MatrixElementEvaluator(self.base_model, auth_skipping = True, reuse = True) p, w_rambo = evaluator.get_momenta(myproc) me_val, amp2 = evaluator.evaluate_matrix_element(\ matrix_element,p) # Rotate momenta around x axis for mom in p: mom[2] = -mom[2] mom[3] = -mom[3] new_me_val, new_amp2 = evaluator.evaluate_matrix_element(\ matrix_element, p) self.assertAlmostEqual(me_val, new_me_val, 10) for amp, new_amp in zip(amp2, new_amp2): self.assertAlmostEqual(amp, new_amp, 10)
def uu_to_ttng_test(self, nglue = 0): """Test the process u u > t t g for 4fermion models""" myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id':2, 'state':False})) myleglist.append(base_objects.Leg({'id':2, 'state':False})) myleglist.append(base_objects.Leg({'id':6})) myleglist.append(base_objects.Leg({'id':6})) myleglist.extend([base_objects.Leg({'id':21}) for i in range(nglue)]) values = {} p = None for model in 'scalar', '4ferm': base_model = eval('self.base_model_%s' % model) full_model = eval('self.full_model_%s' % model) myproc = base_objects.Process({'legs':myleglist, 'model':base_model}) evaluator = process_checks.MatrixElementEvaluator(base_model, reuse = False) evaluator.full_model = full_model if not p: p, w_rambo = evaluator.get_momenta(myproc) amplitude = diagram_generation.Amplitude(myproc) matrix_element = helas_objects.HelasMatrixElement(amplitude) stored_quantities = {} values[model] = evaluator.evaluate_matrix_element(matrix_element, p)[0] self.assertAlmostEqual(values['scalar'], values['4ferm'], 3)
def test_failed_process(self): """Test that check process fails for wrong color-Lorentz.""" # Change 4g interaction so color and lorentz don't agree id = [int.get('id') for int in self.base_model.get('interactions') if [p['pdg_code'] for p in int['particles']] == [21,21,21,21]][0] gggg = self.base_model.get_interaction(id) assert [p['pdg_code'] for p in gggg['particles']] == [21,21,21,21] gggg.set('lorentz', ['VVVV1', 'VVVV4', 'VVVV3']) myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id':21, 'state':False})) myleglist.append(base_objects.Leg({'id':21, 'state':False})) myleglist.append(base_objects.Leg({'id':21, 'state':True})) myleglist.append(base_objects.Leg({'id':21, 'state':True})) myproc = base_objects.Process({'legs':myleglist, 'model':self.base_model}) process_checks.clean_added_globals(process_checks.ADDED_GLOBAL) comparison = process_checks.check_processes(myproc)[0][0] self.assertFalse(comparison['passed']) comparison = process_checks.check_processes(myproc, quick = True)[0][0] self.assertFalse(comparison['passed']) comparison = process_checks.check_gauge(myproc) nb_fail = process_checks.output_gauge(comparison, output='fail') self.assertNotEqual(nb_fail, 0) comparison = process_checks.check_lorentz(myproc) nb_fail = process_checks.output_lorentz_inv(comparison, output='fail') self.assertNotEqual(0, nb_fail)
def test_color_matrix_Nc_restrictions(self): """Test the Nc power restriction during color basis building """ goal = [ fractions.Fraction(3, 8), fractions.Fraction(-9, 4), fractions.Fraction(45, 16) ] for n in range(3): myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id': 21, 'state': False})) myleglist.append(base_objects.Leg({'id': 21, 'state': False})) myleglist.extend([base_objects.Leg({'id': 21, 'state': True})] * 2) myprocess = base_objects.Process({ 'legs': myleglist, 'model': self.mymodel }) myamplitude = diagram_generation.Amplitude() myamplitude.set('process', myprocess) myamplitude.generate_diagrams() col_basis = color_amp.ColorBasis(myamplitude) col_matrix = color_amp.ColorMatrix(col_basis, Nc=3, Nc_power_min=n, Nc_power_max=2 * n) for i in range(len(col_basis.items())): self.assertEqual(col_matrix.col_matrix_fixed_Nc[(i, i)], (goal[n], 0))
def setUp(self): """ Setup the model and the overhead common to all tests """ model_with_params_set = import_ufo.import_model( pjoin(MG5DIR,'models','loop_sm'), prefix=True, complex_mass_scheme = False ) model_with_params_set.pass_particles_name_in_mg_default() model_with_params_set.set_parameters_and_couplings( param_card = pjoin(MG5DIR,'models','loop_sm','restrict_default.dat'), complex_mass_scheme=False ) self.model = model_with_params_set self.current_exporter = subtraction.SubtractionCurrentExporter( self.model, export_dir=None, current_set='colorful') self.walker = walkers.FinalRescalingNLOWalker legs = base_objects.LegList([ base_objects.Leg( {'id': 1, 'state': base_objects.Leg.INITIAL, 'number': 1}), base_objects.Leg( {'id': -1, 'state': base_objects.Leg.INITIAL, 'number': 2}), base_objects.Leg( {'id': 22, 'state': base_objects.Leg.FINAL, 'number': 3}), base_objects.Leg( {'id': 1, 'state': base_objects.Leg.FINAL, 'number': 4}), base_objects.Leg( {'id': -1, 'state': base_objects.Leg.FINAL, 'number': 5}), base_objects.Leg( {'id': 21, 'state': base_objects.Leg.FINAL, 'number': 6}), base_objects.Leg( {'id': 21, 'state': base_objects.Leg.FINAL, 'number': 7}), ]) self.reduced_process = base_objects.Process({ 'legs': legs, 'model': self.model })
def test_export_matrix_element_python_madevent_group(self): """Test the result of exporting a subprocess group matrix element""" # Setup a model mypartlist = base_objects.ParticleList() myinterlist = base_objects.InteractionList() # A gluon mypartlist.append( base_objects.Particle({ 'name': 'g', 'antiname': 'g', 'spin': 3, 'color': 8, 'mass': 'zero', 'width': 'zero', 'texname': 'g', 'antitexname': 'g', 'line': 'curly', 'charge': 0., 'pdg_code': 21, 'propagating': True, 'is_part': True, 'self_antipart': True })) g = mypartlist[-1] # 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 photon mypartlist.append( base_objects.Particle({ 'name': 'a', 'antiname': 'a', 'spin': 3, 'color': 1, 'mass': 'zero', 'width': 'zero', 'texname': '\gamma', 'antitexname': '\gamma', 'line': 'wavy', 'charge': 0., 'pdg_code': 22, 'propagating': True, 'is_part': True, 'self_antipart': True })) a = mypartlist[-1] # 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] # Gluon and photon couplings to quarks myinterlist.append(base_objects.Interaction({ 'id': 1, 'particles': base_objects.ParticleList(\ [antiu, \ u, \ g]), 'color': [], 'lorentz':['L1'], 'couplings':{(0, 0):'GQQ'}, 'orders':{'QCD':1}})) myinterlist.append(base_objects.Interaction({ 'id': 2, 'particles': base_objects.ParticleList(\ [antiu, \ u, \ a]), 'color': [], 'lorentz':['L1'], 'couplings':{(0, 0):'GQED'}, 'orders':{'QED':1}})) myinterlist.append(base_objects.Interaction({ 'id': 3, 'particles': base_objects.ParticleList(\ [antid, \ d, \ g]), 'color': [], 'lorentz':['L1'], 'couplings':{(0, 0):'GQQ'}, 'orders':{'QCD':1}})) myinterlist.append(base_objects.Interaction({ 'id': 4, 'particles': base_objects.ParticleList(\ [antid, \ d, \ a]), 'color': [], 'lorentz':['L1'], 'couplings':{(0, 0):'GQED'}, 'orders':{'QED':1}})) # 3 gluon vertiex myinterlist.append(base_objects.Interaction({ 'id': 5, 'particles': base_objects.ParticleList(\ [g] * 3), 'color': [], 'lorentz':['L1'], 'couplings':{(0, 0):'G'}, 'orders':{'QCD':1}})) # Coupling of Z to quarks myinterlist.append(base_objects.Interaction({ 'id': 6, 'particles': base_objects.ParticleList(\ [antiu, \ u, \ z]), 'color': [], 'lorentz':['L1', 'L2'], 'couplings':{(0, 0):'GUZ1', (0, 1):'GUZ2'}, 'orders':{'QED':1}})) myinterlist.append(base_objects.Interaction({ 'id': 7, 'particles': base_objects.ParticleList(\ [antid, \ d, \ z]), 'color': [], 'lorentz':['L1', 'L2'], 'couplings':{(0, 0):'GDZ1', (0, 0):'GDZ2'}, 'orders':{'QED':1}})) mymodel = base_objects.Model() mymodel.set('particles', mypartlist) mymodel.set('interactions', myinterlist) procs = [[2, -2, 21, 21], [2, -2, 2, -2]] amplitudes = diagram_generation.AmplitudeList() 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) amplitudes.append(my_amplitude) # Calculate diagrams for all processes subprocess_group = group_subprocs.SubProcessGroup.\ group_amplitudes(amplitudes, "madevent")[0] # Test amp2 lines helas_writer = helas_call_writers.PythonUFOHelasCallWriter(mymodel) python_exporter = export_python.ProcessExporterPython( subprocess_group, helas_writer) amp2_lines = \ python_exporter.get_amp2_lines(subprocess_group.\ get('matrix_elements')[0], subprocess_group.get('diagram_maps')[0]) self.assertEqual(amp2_lines, [ 'self.amp2[0]+=abs(amp[0]*amp[0].conjugate())', 'self.amp2[1]+=abs(amp[1]*amp[1].conjugate())', 'self.amp2[2]+=abs(amp[2]*amp[2].conjugate())' ])
def test_color_matrix_multi_quarks(self): """Test the color matrix building for qq~ > n*(qq~) with n up to 2""" goal = [fractions.Fraction(9, 1), fractions.Fraction(27, 1)] goal_line1 = [(fractions.Fraction(9, 1), fractions.Fraction(3, 1)), (fractions.Fraction(27, 1), fractions.Fraction(9, 1), fractions.Fraction(9, 1), fractions.Fraction(3, 1), fractions.Fraction(3, 1), fractions.Fraction(9, 1))] goal_den_list = [[1] * 2, [1] * 6] goal_first_line_num = [[9, 3], [27, 9, 9, 3, 3, 9]] for n in range(2): myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id': -2, 'state': False})) myleglist.append(base_objects.Leg({'id': 2, 'state': False})) myleglist.extend([ base_objects.Leg({ 'id': -2, 'state': True }), base_objects.Leg({ 'id': 2, 'state': True }) ] * (n + 1)) myprocess = base_objects.Process({ 'legs': myleglist, 'model': self.mymodel }) myamplitude = diagram_generation.Amplitude() myamplitude.set('process', myprocess) myamplitude.generate_diagrams() col_basis = color_amp.ColorBasis(myamplitude) col_matrix = color_amp.ColorMatrix(col_basis, Nc=3) # Check diagonal for i in range(len(col_basis.items())): self.assertEqual(col_matrix.col_matrix_fixed_Nc[(i, i)], (goal[n], 0)) # Check first line for i in range(len(col_basis.items())): self.assertEqual(col_matrix.col_matrix_fixed_Nc[(0, i)], (goal_line1[n][i], 0)) self.assertEqual(col_matrix.get_line_denominators(), goal_den_list[n]) self.assertEqual( col_matrix.get_line_numerators( 0, col_matrix.get_line_denominators()[0]), goal_first_line_num[n])
def test_triplet_color_flow_output(self): """Test the color flow output for color triplets""" # Test u u > trip~ g myleglist = base_objects.LegList() myleglist.append( base_objects.Leg({ 'id': 2, 'state': False, 'number': 1 })) myleglist.append( base_objects.Leg({ 'id': 6, 'state': False, 'number': 2 })) myleglist.append( base_objects.Leg({ 'id': -9000006, 'state': True, 'number': 3 })) myleglist.append( base_objects.Leg({ 'id': 21, 'state': True, 'number': 4 })) myproc = base_objects.Process({ 'legs': myleglist, 'model': self.base_model }) myamp = diagram_generation.Amplitude(myproc) matrix_element = helas_objects.HelasMatrixElement(myamp) # First build a color representation dictionnary repr_dict = {} for l in myleglist: repr_dict[l.get('number')] = \ self.base_model.get_particle(l.get('id')).get_color() # Get the color flow decomposition col_flow = \ matrix_element.get('color_basis').color_flow_decomposition(repr_dict, 2) self.assertEqual(col_flow, [{ 1: [501, 0], 2: [502, 0], 3: [0, 504], 4: [504, 503] }, { 1: [501, 0], 2: [504, 0], 3: [0, 502], 4: [504, 503] }, { 1: [504, 0], 2: [501, 0], 3: [0, 502], 4: [504, 503] }]) # Test u u > trip~ > u u g myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id': 2, 'state': False})) myleglist.append(base_objects.Leg({'id': 6, 'state': False})) myleglist.append(base_objects.Leg({'id': 2, 'state': True})) myleglist.append(base_objects.Leg({'id': 6, 'state': True})) myleglist.append(base_objects.Leg({'id': 21, 'state': True})) myproc = base_objects.Process({ 'legs': myleglist, 'model': self.base_model, 'required_s_channels': [[-9000006]] }) myamp = diagram_generation.Amplitude(myproc) self.assertEqual(len(myamp.get('diagrams')), 5) matrix_element = helas_objects.HelasMatrixElement(myamp) # First build a color representation dictionnary repr_dict = {} for l in myleglist: repr_dict[l.get('number')] = \ self.base_model.get_particle(l.get('id')).get_color() # Get the color flow decomposition col_flow = \ matrix_element.get('color_basis').color_flow_decomposition(repr_dict, 2) self.assertEqual(col_flow, [{ 1: [501, 0], 2: [502, 0], 3: [504, 0], 4: [505, 0], 5: [506, 503] }, { 1: [501, 0], 2: [503, 0], 3: [501, 0], 4: [502, 0], 5: [503, 502] }, { 1: [503, 0], 2: [501, 0], 3: [501, 0], 4: [502, 0], 5: [503, 502] }, { 1: [502, 0], 2: [503, 0], 3: [501, 0], 4: [502, 0], 5: [503, 501] }, { 1: [503, 0], 2: [502, 0], 3: [501, 0], 4: [502, 0], 5: [503, 501] }])
def setUp(self): # Set up model mypartlist = base_objects.ParticleList() myinterlist = base_objects.InteractionList() # A photon mypartlist.append( base_objects.Particle({ 'name': 'a', 'antiname': 'a', 'spin': 3, 'color': 1, 'mass': 'zero', 'width': 'zero', 'texname': '\gamma', 'antitexname': '\gamma', 'line': 'wavy', 'charge': 0., 'pdg_code': 22, 'propagating': True, 'is_part': True, 'self_antipart': True })) a = mypartlist[len(mypartlist) - 1] # W+ and W- mypartlist.append( base_objects.Particle({ 'name': 'w+', 'antiname': 'w-', 'spin': 3, 'color': 1, 'mass': 'wmas', 'width': 'wwid', 'texname': 'W^+', 'antitexname': 'W^-', 'line': 'wavy', 'charge': 1., 'pdg_code': 24, 'propagating': True, 'is_part': True, 'self_antipart': False })) wplus = mypartlist[len(mypartlist) - 1] wminus = copy.copy(wplus) wminus.set('is_part', False) # Z mypartlist.append( base_objects.Particle({ 'name': 'z', 'antiname': 'z', 'spin': 3, 'color': 1, 'mass': 'zmas', 'width': 'zwid', 'texname': 'Z', 'antitexname': 'Z', 'line': 'wavy', 'charge': 1., 'pdg_code': 23, 'propagating': True, 'is_part': True, 'self_antipart': True })) z = mypartlist[len(mypartlist) - 1] # a-a-w+w- 4-vertex myinterlist.append(base_objects.Interaction({ 'id': 1, 'particles': base_objects.ParticleList(\ [a, \ a, wminus, wplus]), 'color': [], 'lorentz':['VVVV1'], 'couplings':{(0, 0):'GC_51'}, 'orders':{'QED':2}})) # w+w-z vertex myinterlist.append(base_objects.Interaction({ 'id': 2, 'particles': base_objects.ParticleList(\ [wminus, wplus, z]), 'color': [], 'lorentz':['VVV1'], 'couplings':{(0, 0):'GC_12'}, 'orders':{'QED':1}})) self.mybasemodel.set('particles', mypartlist) self.mybasemodel.set('interactions', myinterlist) self.mybasemodel.set('name', 'sm') #import madgraph.interface.cmd_interface as cmd #CMD = cmd.MadGraphCmdShell() #CMD._curr_model = self.mybasemodel #CMD._curr_fortran_model = helas_call_writers.FortranUFOHelasCallWriter #CMD.do_generate('a w- > w- a z') #CMD.do_export('matrix_v4 /tmp/') leg1 = base_objects.Leg({'id': 22, 'state': False}) leg2 = base_objects.Leg({'id': 24, 'state': False}) leg3 = base_objects.Leg({'id': 22, 'state': True}) leg4 = base_objects.Leg({'id': 24, 'state': True}) leg5 = base_objects.Leg({'id': 23, 'state': True}) legList1 = base_objects.LegList([leg1, leg2, leg3, leg4, leg5]) myproc = base_objects.Process({ 'legs': legList1, 'model': self.mybasemodel }) myamplitude = diagram_generation.Amplitude({'process': myproc}) self.mymatrixelement = helas_objects.HelasMatrixElement(myamplitude)
class LoopDiagramDrawerTest(unittest.TestCase): """Test class for all functions related to the LoopDiagramDrawer diagram made by hand """ myloopmodel = loop_base_objects.LoopModel() mypartlist = base_objects.ParticleList() myinterlist = base_objects.InteractionList() mymodel = base_objects.Model() myproc = base_objects.Process() def setUp(self): """ Setup a toy-model with gluon and down-quark only """ # A gluon self.mypartlist.append( base_objects.Particle({ 'name': 'g', 'antiname': 'g', 'spin': 3, 'color': 8, 'mass': 'zero', 'width': 'zero', 'texname': 'g', 'antitexname': 'g', 'line': 'curly', 'charge': 0., 'pdg_code': 21, 'propagating': True, 'is_part': True, 'self_antipart': True })) # A quark D and its antiparticle self.mypartlist.append( base_objects.Particle({ 'name': 'd', 'antiname': 'd~', 'spin': 2, 'color': 3, 'mass': 'dmass', 'width': 'zero', 'texname': 'd', 'antitexname': '\bar d', 'line': 'straight', 'charge': -1. / 3., 'pdg_code': 1, 'propagating': True, 'is_part': True, 'self_antipart': False })) antid = copy.copy(self.mypartlist[1]) antid.set('is_part', False) # 3 gluon vertex self.myinterlist.append(base_objects.Interaction({ 'id': 1, 'particles': base_objects.ParticleList(\ [self.mypartlist[0]] * 3), 'color': [], 'lorentz':['L1'], 'couplings':{(0, 0):'G'}, 'orders':{'QCD':1}})) # 4 gluon vertex self.myinterlist.append(base_objects.Interaction({ 'id': 2, 'particles': base_objects.ParticleList(\ [self.mypartlist[0]] * 4), 'color': [], 'lorentz':['L1'], 'couplings':{(0, 0):'G^2'}, 'orders':{'QCD':2}})) # Gluon coupling to the down-quark self.myinterlist.append(base_objects.Interaction({ 'id': 3, 'particles': base_objects.ParticleList(\ [self.mypartlist[1], \ antid, \ self.mypartlist[0]]), 'color': [], 'lorentz':['L1'], 'couplings':{(0, 0):'GQQ'}, 'orders':{'QCD':1}})) self.mymodel.set('particles', self.mypartlist) self.mymodel.set('interactions', self.myinterlist) self.myproc.set('model', self.mymodel) self.myloopmodel = save_load_object.load_from_file(os.path.join(_input_file_path,\ 'test_toyLoopModel.pkl')) box_diagram, box_struct = self.def_box() pent_diagram, pent_struct = self.def_pent() self.box_drawing = draw_lib.LoopFeynmanDiagram(box_diagram, box_struct, self.myloopmodel) def test_fuse_line(self): """ check that we fuse line correctly """ self.box_drawing.load_diagram() #avoid that element are erase from memory line1 = self.box_drawing.lineList[0] line2 = self.box_drawing.lineList[1] vertex1 = line1.begin vertex2 = line1.end vertex3 = line2.begin vertex4 = line2.end # fuse line1 and line2 self.box_drawing.fuse_line(line1, line2) # check that all link to line1 are ok self.assertEqual(line1.begin, vertex1) self.assertEqual(line1.end, vertex3) self.assertTrue(line1 in vertex1.lines) self.assertTrue(line1 in vertex3.lines) #self.assertTrue(vertex1 in self.box_drawing.vertexList) #self.assertTrue(vertex4 in self.box_drawing.vertexList) #check that all info to line2 are deleted self.assertFalse(line2 in self.box_drawing.lineList) self.assertFalse(line2 in vertex1.lines) self.assertFalse(line2 in vertex3.lines) self.assertFalse(vertex2 in self.box_drawing.vertexList) self.assertFalse(vertex3 in self.box_drawing.vertexList) def def_box(self): """ Test the drawing of a simple loop box """ myleglist = base_objects.LegList([base_objects.Leg({'id':21, 'number':num, 'state':True, 'loop_line':False}) \ for num in range(1, 5)]) myleglist.append( base_objects.Leg({ 'id': 1, 'number': 5, 'loop_line': True })) myleglist.append( base_objects.Leg({ 'id': -1, 'number': 6, 'loop_line': True })) l1 = myleglist[0] l1.set('state', False) l2 = myleglist[1] l2.set('state', False) l3 = myleglist[2] l4 = myleglist[3] l5 = myleglist[4] l6 = myleglist[5] # One way of constructing this diagram, with a three-point amplitude l15 = base_objects.Leg({ 'id': 1, 'number': 1, 'loop_line': True, 'state': False }) l12 = base_objects.Leg({'id': 1, 'number': 1, 'loop_line': True}) l13 = base_objects.Leg({'id': 1, 'number': 1, 'loop_line': True}) lfake = base_objects.Leg({'id': 1, 'number': 1, 'loop_line': True}) vx15 = base_objects.Vertex({ 'legs': base_objects.LegList([l1, l5, l15]), 'id': 3 }) vx12 = base_objects.Vertex({ 'legs': base_objects.LegList([l15, l2, l12]), 'id': 3 }) vx13 = base_objects.Vertex({ 'legs': base_objects.LegList([l12, l3, l13]), 'id': 3 }) vx164 = base_objects.Vertex({ 'legs': base_objects.LegList([l13, l6, l4]), 'id': 3 }) fakevx = base_objects.Vertex({ 'legs': base_objects.LegList([l13, lfake]), 'id': 0 }) ctvx = base_objects.Vertex({ 'legs': base_objects.LegList([l1, l2, l3, l4]), 'id': 666 }) myVertexList1 = base_objects.VertexList([vx15, vx12, vx13, vx164]) myCTVertexList = base_objects.VertexList([ ctvx, ]) myPentaDiag1=loop_base_objects.LoopDiagram({'vertices':myVertexList1,'type':1,\ 'CT_vertices':myCTVertexList}) return myPentaDiag1, [] def def_pent(self): """ Test the gg>gggg d*dx* tagging of a quark pentagon which is tagged""" # Five gluon legs with two initial states myleglist = base_objects.LegList([base_objects.Leg({'id':21, 'number':num, 'loop_line':False}) \ for num in range(1, 7)]) myleglist.append( base_objects.Leg({ 'id': 1, 'number': 7, 'loop_line': True })) myleglist.append( base_objects.Leg({ 'id': -1, 'number': 8, 'loop_line': True })) l1 = myleglist[0] l2 = myleglist[1] l3 = myleglist[2] l4 = myleglist[3] l5 = myleglist[4] l6 = myleglist[5] l7 = myleglist[6] l8 = myleglist[7] # One way of constructing this diagram, with a three-point amplitude l17 = base_objects.Leg({'id': 1, 'number': 1, 'loop_line': True}) l12 = base_objects.Leg({'id': 1, 'number': 1, 'loop_line': True}) l68 = base_objects.Leg({'id': -1, 'number': 6, 'loop_line': True}) l56 = base_objects.Leg({'id': -1, 'number': 5, 'loop_line': True}) l34 = base_objects.Leg({'id': 21, 'number': 3, 'loop_line': False}) self.myproc.set('legs', myleglist) vx17 = base_objects.Vertex({ 'legs': base_objects.LegList([l1, l7, l17]), 'id': 3 }) vx12 = base_objects.Vertex({ 'legs': base_objects.LegList([l17, l2, l12]), 'id': 3 }) vx68 = base_objects.Vertex({ 'legs': base_objects.LegList([l6, l8, l68]), 'id': 3 }) vx56 = base_objects.Vertex({ 'legs': base_objects.LegList([l5, l68, l56]), 'id': 3 }) vx34 = base_objects.Vertex({ 'legs': base_objects.LegList([l3, l4, l34]), 'id': 1 }) vx135 = base_objects.Vertex({ 'legs': base_objects.LegList([l12, l56, l34]), 'id': 3 }) myVertexList1 = base_objects.VertexList( [vx17, vx12, vx68, vx56, vx34, vx135]) myPentaDiag1 = loop_base_objects.LoopDiagram({ 'vertices': myVertexList1, 'type': 1 }) myStructRep = loop_base_objects.FDStructureList() myPentaDiag1.tag(myStructRep, self.myproc['model'], 7, 8) return myPentaDiag1, myStructRep # test the drawing of myPentaDiag with its loop vertices and those in the # structures of myStructRep def def_diagrams_epemddx(self): """ Test the drawing of diagrams from the loop process e+e- > dd~ """ myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id': -11, 'state': False})) myleglist.append(base_objects.Leg({'id': 11, 'state': False})) myleglist.append(base_objects.Leg({'id': 1, 'state': True})) myleglist.append(base_objects.Leg({'id': -1, 'state': True})) myproc = base_objects.Process({ 'legs': myleglist, 'model': self.myloopmodel, 'orders': {}, 'perturbation_couplings': [ 'QCD', ], 'squared_orders': {} }) myloopamplitude = loop_diagram_generation.LoopAmplitude() myloopamplitude.set('process', myproc) myloopamplitude.generate_diagrams() # Now the drawing test on myloopamplitude['loop_diagrams'] return myloopamplitude['loop_diagrams']
class ME7ContributionTest(IOTests.IOTestManager): """Test class for functionalities related to contributions.""" mymodel = loop_base_objects.LoopModel() mylegs = base_objects.LegList() myprocess = base_objects.Process() # To be set during setUp LO_contributions = None NLO_contributions = None @misc.mute_logger() def setUp(self): self.mymodel = import_ufo.import_model( pjoin(MG5DIR,'tests','input_files','LoopSMTest'), prefix=True, complex_mass_scheme = False ) self.mymodel.pass_particles_name_in_mg_default() # Setting up the process p p > h j j and its subtraction self.mylegs = base_objects.MultiLegList([ base_objects.MultiLeg( {'ids': [1,2,-1,-2,21], 'state': base_objects.Leg.INITIAL}), base_objects.MultiLeg( {'ids': [1,2,-1,-2,21], 'state': base_objects.Leg.INITIAL}), base_objects.MultiLeg( {'ids': [22], 'state': base_objects.Leg.FINAL}), base_objects.MultiLeg( {'ids': [21,1,-1,2,-2], 'state': base_objects.Leg.FINAL}) ]) self.myprocdef = base_objects.ProcessDefinition({ 'legs': self.mylegs, 'model': self.mymodel, 'split_orders': ['QCD','QED'] }) # The general accessor with the Born ME registered self.all_born_MEs_accessor = accessors.MEAccessorDict() # Generate only Born LO contributions with misc.TMP_directory(debug=False) as tmp_path: # Generate the output for this. self.madgraph_cmd = cmd.MasterCmd(main='MadGraph') self.madgraph_cmd._curr_model = self.mymodel self.madgraph_cmd.reset_interface_before_new_generation() self.madgraph_cmd._export_dir = pjoin(tmp_path,'ME7ContributionTest_LO') # Generate contributions generation_options = {'ME7_definition': True, 'diagram_filter': False, 'LO': True, 'NNLO': [], 'NNNLO': [], 'optimize': False, 'NLO': [], 'loop_induced': [], 'ignore_contributions' : [], 'beam_types': ['auto', 'auto'], 'loop_filter' : None, 'process_definitions' : {}} self.madgraph_cmd.add_contributions(self.myprocdef, generation_options) LO_contributions = self.madgraph_cmd._curr_contribs LO_contributions.apply_method_to_all_contribs( 'generate_amplitudes', log='Generate diagrams for') self.exporter = export_ME7.ME7Exporter( self.madgraph_cmd, False, group_subprocesses=True ) self.exporter.pass_information_from_cmd(self.madgraph_cmd) self.exporter.copy_template(self.madgraph_cmd._curr_model) self.exporter.export(True, args=[]) # We want to finalize and output the model for the Born, because need to # register its MEs in the accessor. self.exporter.finalize(['nojpeg'], self.madgraph_cmd.history) self.LO_contributions = self.madgraph_cmd._curr_contribs # Add the Born ME accessors to the dictionary self.LO_contributions[0].add_ME_accessors( self.all_born_MEs_accessor, pjoin(tmp_path,'ME7ContributionTest_LO') ) # Generate all NLO contributions with misc.TMP_directory(debug=False) as tmp_path: # Generate the output for this. self.madgraph_cmd = cmd.MasterCmd(main='MadGraph') self.madgraph_cmd._curr_model = self.mymodel self.madgraph_cmd.reset_interface_before_new_generation() self.madgraph_cmd._export_dir = pjoin(tmp_path,'ME7ContributionTest_LO') # Generate contributions generation_options = {'ME7_definition': True, 'diagram_filter': False, 'LO': True, 'NNLO': [], 'NNNLO': [], 'optimize': False, 'NLO': ['QCD'], 'loop_induced': [], 'ignore_contributions' : [], 'beam_types': ['auto', 'auto'], 'loop_filter' : None, 'process_definitions' : {}, } self.madgraph_cmd.add_contributions(self.myprocdef, generation_options) self.madgraph_cmd._curr_contribs.apply_method_to_all_contribs( 'generate_amplitudes', log='Generate diagrams for') self.exporter = export_ME7.ME7Exporter( self.madgraph_cmd, False, group_subprocesses=True ) self.exporter.pass_information_from_cmd(self.madgraph_cmd) self.exporter.copy_template(self.madgraph_cmd._curr_model) self.exporter.export(True, args=[]) # The export above was enough to have fully functional contributions to test # self.exporter.finalize(['nojpeg'], self.madgraph_cmd.history) self.NLO_contributions = self.madgraph_cmd._curr_contribs @IOTests.createIOTest() def testIO_current_generation_and_access(self): """ target: Counterterms_R.txt target: Counterterms_V.txt target: Currents_Local.txt target: Currents_Integ.txt """ # Test the generation of counterterms in single real-emission and virtual # type of contributions. Also make sure that they can be exported. verbose = False # Real counterterms # Fetch the real contribution real_emission_contrib = self.NLO_contributions.get_contributions_of_type( contributions.Contribution_R )[0] # Use the ME accessor dictionary with all Born MEs to filter # the unphysical counterterms, # for example those with the reduced process g g > a g n_CTs_before_filtering = len( sum(real_emission_contrib.counterterms.values(), []) ) for CT_list in real_emission_contrib.counterterms.values(): contributions.Contribution_R.remove_counterterms_with_no_reduced_process( self.all_born_MEs_accessor, CT_list ) n_CTs_after_filtering = len( sum(real_emission_contrib.counterterms.values(), []) ) n_CTs_difference = n_CTs_before_filtering - n_CTs_after_filtering if verbose: print_string = 'A total of %d local counterterms were filtered' print_string += 'because a reduced process did not exist.' misc.sprint(print_string % (n_CTs_difference)) # Check the number of filtered local counterterms self.assertEqual(n_CTs_difference, 6) # Output all local counterterms counterterm_strings = [ CT.__str__(print_n=True, print_pdg=True, print_state=True) for CT in sum(real_emission_contrib.counterterms.values(), []) ] open(pjoin(self.IOpath,'Counterterms_R.txt'),'w').write( "\n".join(sorted(counterterm_strings)) ) # Virtual counterterms # Fetch the virtual contribution virtual_contrib = self.NLO_contributions.get_contributions_of_type( contributions.Contribution_V)[0] # Apply the filter to integrated counterterms n_CTs_before_filtering = len( sum(virtual_contrib.integrated_counterterms.values(),[]) ) for CT_list in virtual_contrib.integrated_counterterms.values(): contributions.Contribution_V.remove_counterterms_with_no_reduced_process( self.all_born_MEs_accessor, CT_list ) n_CTs_after_filtering = len( sum(virtual_contrib.integrated_counterterms.values(),[]) ) n_CTs_difference = n_CTs_before_filtering - n_CTs_after_filtering if verbose: print_string = 'A total of %d integrated counterterms were filtered' print_string += 'because a reduced process did not exist.' misc.sprint(print_string % (n_CTs_difference)) # Check the number of filtered integrated counterterms self.assertEqual(n_CTs_difference, 0) # Output all integrated counterterms counterterm_strings = [ CT['integrated_counterterm'].__str__( print_n=True, print_pdg=True, print_state=True ) for CT in sum(virtual_contrib.integrated_counterterms.values(), []) ] open(pjoin(self.IOpath,'Counterterms_V.txt'),'w').write( "\n".join(sorted(counterterm_strings)) ) # Check the number of counterterms that did not find a host contribution refused_cts = len(self.exporter.integrated_counterterms_refused_from_all_contribs) if verbose: print_string = 'A total of %d integrated subtraction counterterms' print_string += 'did not find a host contribution.' misc.sprint(print_string % refused_cts) self.assertEqual(refused_cts, 14) # Local currents # Initialize an empty accessor dictionary for the currents. # No currents are ignored because of potential pre-existing ones. accessors_dict = accessors.MEAccessorDict() all_local_currents = \ real_emission_contrib.get_all_necessary_local_currents(accessors_dict) current_strings = [str(current) for current in all_local_currents] # Print all local currents if verbose: misc.sprint('Local currents:\n' + '\n'.join(current_strings)) # Output all local currents open(pjoin(self.IOpath, 'Currents_Local.txt'), 'w').write( "\n".join(sorted(current_strings)) ) # Integrated currents # Use the ME accessor dictionary with all Born MEs to filter what are the # unphysical counterterms, for example those with the reduced process g g > a g all_integrated_currents = virtual_contrib.get_all_necessary_integrated_currents( self.all_born_MEs_accessor ) current_strings = [str(current) for current in all_integrated_currents] # Print all currents if verbose: misc.sprint('Integrated currents:\n' + '\n'.join(current_strings)) # Output all local currents open(pjoin(self.IOpath, 'Currents_Integ.txt'), 'w').write( "\n".join(sorted(current_strings)) ) with misc.TMP_directory(debug=False) as tmp_path: print_string = "A total of %d accessor keys have been generated" print_string += "for %s subtraction currents." # Reset the accessor dictionary so as to monitor only the newly added keys accessors_dict = accessors.MEAccessorDict() real_emission_contrib.add_current_accessors( self.mymodel, accessors_dict, tmp_path, 'colorful', all_local_currents ) # Print all accessor keys if verbose: misc.sprint(print_string % (len(accessors_dict), "local")) self.assertEqual(len(accessors_dict), 43) # Reset the accessor dictionary so as to monitor only the newly added keys accessors_dict = accessors.MEAccessorDict() virtual_contrib.add_current_accessors( self.mymodel, accessors_dict, tmp_path, 'colorful', all_integrated_currents ) # Print all accessor keys if verbose: misc.sprint(print_string % (len(accessors_dict), "integrated")) self.assertEqual(len(accessors_dict), 50)
class WalkersTest(unittest.TestCase): """Test class for walkers.""" # Parameters #===================================================================================== # Verbosity (silent = 0, max = 4) verbosity = 0 # Random seed to make tests deterministic seed = 42 # Number of PS points the invertibility test is run for (more = stronger, slower test) n_test_invertible = 3 # Number of PS points the approach_limit test is run for (more = stronger, slower test) n_test_approach = 5 # Number of PS points for the low_level_approach_limit test (more = stronger, slower test) n_test_low_level_approach = 100 # Values of the parameter in approach_limit (more, smaller = stronger, slower test) parameter_values = [0.1**i for i in range(5)] # Setup #===================================================================================== # IRSubtraction module irs = subtraction.IRSubtraction(simple_qcd.model, coupling_types=('QCD', ), n_unresolved=None) # Not aligning the initial state with z avoids numerical issues initial_along_z = False # Separator for output stars = "*" * 90 # Functions #===================================================================================== @classmethod def generate_PS_point(cls, process): """Generate a phase-space point to test the walker.""" model = process.get('model') # Generate random vectors my_PS_point = LorentzVectorDict() legs_FS = tuple( subtraction.SubtractionLeg(leg) for leg in process['legs'] if leg['state'] == FINAL) for leg in legs_FS: my_PS_point[leg.n] = random_momentum( simple_qcd.masses[model.get_particle(leg.pdg)['mass']]) total_momentum = LorentzVector() for leg in legs_FS: total_momentum += my_PS_point[leg.n] legs_IS = tuple( subtraction.SubtractionLeg(leg) for leg in process['legs'] if leg['state'] == INITIAL) if len(legs_IS) == 1: my_PS_point[legs_IS[0].n] = total_momentum elif len(legs_IS) == 2: if cls.initial_along_z: bv = total_momentum.boostVector() for key in my_PS_point.keys(): my_PS_point[key].boost(-bv) total_momentum.boost(-bv) E = total_momentum[0] my_PS_point[1] = LorentzVector([E / 2., 0., 0., +E / 2.]) my_PS_point[2] = LorentzVector([E / 2., 0., 0., -E / 2.]) else: E = abs(total_momentum.square())**0.5 rest_momentum = LorentzVector([E, 0., 0., 0.]) my_PS_point[1] = LorentzVector([E / 2., 0., 0., +E / 2.]) my_PS_point[2] = LorentzVector([E / 2., 0., 0., -E / 2.]) my_PS_point[1].rotoboost(rest_momentum, total_momentum) my_PS_point[2].rotoboost(rest_momentum, total_momentum) else: raise BaseException return my_PS_point def _test_approach_limit(self, walker, process, max_unresolved_in_elementary, max_unresolved_in_combination): """Check that the walker is capable of approaching limits. :param walker: Mapping walker to be tested :type walker: walkers.VirtualWalker :param process: The physical process the walker will be tested for :type process: base_objects.Process :param max_unresolved_in_elementary: Maximum number of unresolved particles within the same elementary operator :type max_unresolved_in_elementary: positive integer :param max_unresolved_in_combination: Maximum number of unresolved particles within a combination of elementary operators :type max_unresolved_in_combination: positive integer """ if self.verbosity > 2: print "\n" + self.stars * (self.verbosity - 2) if self.verbosity > 0: tmp_str = "test_approach_limit for " + walker.__class__.__name__ tmp_str += " with " + process.nice_string() print tmp_str if self.verbosity > 2: print self.stars * (self.verbosity - 2) + "\n" random.seed(self.seed) # Generate all counterterms for this process, and separate the non-singular one my_operators = self.irs.get_all_elementary_operators( process, max_unresolved_in_elementary) my_combinations = self.irs.get_all_combinations( my_operators, max_unresolved_in_combination) my_counterterms = [ self.irs.get_counterterm(combination, process) for combination in my_combinations ] # Get all legs in the FS and the model to check masses after approach_limit legs_FS = tuple( subtraction.SubtractionLeg(leg) for leg in process['legs'] if leg['state'] == FINAL) model = process.get('model') # For each counterterm for ct in my_counterterms: if not ct.is_singular(): continue if self.verbosity > 3: print "\n" + self.stars * (self.verbosity - 3) if self.verbosity > 1: print "Considering counterterm", ct if self.verbosity > 3: print self.stars * (self.verbosity - 3) + "\n" ss = ct.reconstruct_complete_singular_structure() for j in range(self.n_test_invertible): if self.verbosity > 2: print "Phase space point #", j + 1 # Generate random vectors my_PS_point = self.generate_PS_point(process) if self.verbosity > 3: print "Starting phase space point:\n", my_PS_point, "\n" squares = { key: my_PS_point[key].square() for key in my_PS_point.keys() } # Compute collinear variables for alpha in self.parameter_values: new_PS_point = walker.approach_limit( my_PS_point, ss, alpha, process) if self.verbosity > 4: print "New PS point for", alpha, ":\n", new_PS_point for leg in legs_FS: if model.get_particle( leg.pdg)['mass'].lower() == 'zero': self.assertLess(abs(new_PS_point[leg.n].square()), math.sqrt(new_PS_point[leg.n].eps)) else: self.assertAlmostEqual( new_PS_point[leg.n].square(), squares[leg.n]) def _test_low_level_approach_limit(self, process, low_level_limit): model = process.get('model') legs = process.get('legs') for j in range(self.n_test_low_level_approach): if self.verbosity > 0: print "Phase space point #", j + 1 my_PS_point = self.generate_PS_point(process) clean_momenta_dict = subtraction.IRSubtraction.create_momenta_dict( process) new_PS_point = walkers.low_level_approach_limit( my_PS_point, low_level_limit, 10**(-8 * random.random()), clean_momenta_dict, verbose=True) # Sanity checks on masses and energy positivity for leg in legs: pdg = leg['id'] n = leg['number'] if model.get_particle(pdg)['mass'].lower() == 'zero': self.assertLess(abs(new_PS_point[n].square()), math.sqrt(new_PS_point[n].eps())) else: self.assertAlmostEqual(new_PS_point[n].square(), my_PS_point[n].square()) self.assertTrue( new_PS_point[n][0] > 0 or abs(new_PS_point[n][0]) < new_PS_point[n].eps()) # Processes #===================================================================================== # H > u u~ d d~ H_to_uuxddx_legs = base_objects.LegList([ base_objects.Leg({ 'number': 1, 'id': 25, 'state': INITIAL }), base_objects.Leg({ 'number': 2, 'id': 1, 'state': FINAL }), base_objects.Leg({ 'number': 3, 'id': -1, 'state': FINAL }), base_objects.Leg({ 'number': 4, 'id': 2, 'state': FINAL }), base_objects.Leg({ 'number': 5, 'id': -2, 'state': FINAL }), ]) H_to_uuxddx = base_objects.Process({ 'legs': H_to_uuxddx_legs, 'model': simple_qcd.model, 'n_loops': 0 }) # H > u u~ d d~ g H_to_uuxddxg_legs = base_objects.LegList([ base_objects.Leg({ 'number': 1, 'id': 25, 'state': INITIAL }), base_objects.Leg({ 'number': 2, 'id': 1, 'state': FINAL }), base_objects.Leg({ 'number': 3, 'id': -1, 'state': FINAL }), base_objects.Leg({ 'number': 4, 'id': 2, 'state': FINAL }), base_objects.Leg({ 'number': 5, 'id': -2, 'state': FINAL }), base_objects.Leg({ 'number': 6, 'id': 21, 'state': FINAL }), ]) H_to_uuxddxg = base_objects.Process({ 'legs': H_to_uuxddxg_legs, 'model': simple_qcd.model, 'n_loops': 0 }) # H > u u~ d d~ H H_to_uuxddxH_legs = base_objects.LegList([ base_objects.Leg({ 'number': 1, 'id': 25, 'state': INITIAL }), base_objects.Leg({ 'number': 2, 'id': 1, 'state': FINAL }), base_objects.Leg({ 'number': 3, 'id': -1, 'state': FINAL }), base_objects.Leg({ 'number': 4, 'id': 2, 'state': FINAL }), base_objects.Leg({ 'number': 5, 'id': -2, 'state': FINAL }), base_objects.Leg({ 'number': 6, 'id': 25, 'state': FINAL }), ]) H_to_uuxddxH = base_objects.Process({ 'legs': H_to_uuxddxH_legs, 'model': simple_qcd.model, 'n_loops': 0 }) # H > b b~ u u~ g g g H_to_bbxuuxggg_legs = base_objects.LegList([ base_objects.Leg({ 'number': 1, 'id': 25, 'state': INITIAL }), base_objects.Leg({ 'number': 2, 'id': 1, 'state': FINAL }), base_objects.Leg({ 'number': 3, 'id': -1, 'state': FINAL }), base_objects.Leg({ 'number': 4, 'id': 2, 'state': FINAL }), base_objects.Leg({ 'number': 5, 'id': -2, 'state': FINAL }), base_objects.Leg({ 'number': 6, 'id': 21, 'state': FINAL }), base_objects.Leg({ 'number': 7, 'id': 21, 'state': FINAL }), base_objects.Leg({ 'number': 8, 'id': 21, 'state': FINAL }), ]) H_to_bbxuuxggg = base_objects.Process({ 'legs': H_to_bbxuuxggg_legs, 'model': simple_qcd.model, 'n_loops': 0 }) # H > q q~ g g H H_to_qqxggH_legs = base_objects.LegList([ base_objects.Leg({ 'number': 1, 'id': 25, 'state': INITIAL }), base_objects.Leg({ 'number': 2, 'id': 1, 'state': FINAL }), base_objects.Leg({ 'number': 3, 'id': -1, 'state': FINAL }), base_objects.Leg({ 'number': 4, 'id': 21, 'state': FINAL }), base_objects.Leg({ 'number': 5, 'id': 21, 'state': FINAL }), base_objects.Leg({ 'number': 6, 'id': 25, 'state': FINAL }), ]) H_to_qqxggH = base_objects.Process({ 'legs': H_to_qqxggH_legs, 'model': simple_qcd.model, 'n_loops': 0 }) # q q~ > g g H # HACK: one gluon more to avoid issue with final-only soft mapping qqx_to_ggH_legs = base_objects.LegList([ base_objects.Leg({ 'number': 1, 'id': 1, 'state': INITIAL }), base_objects.Leg({ 'number': 2, 'id': -1, 'state': INITIAL }), base_objects.Leg({ 'number': 3, 'id': 21, 'state': FINAL }), base_objects.Leg({ 'number': 4, 'id': 21, 'state': FINAL }), base_objects.Leg({ 'number': 5, 'id': 21, 'state': FINAL }), base_objects.Leg({ 'number': 6, 'id': 25, 'state': FINAL }), ]) qqx_to_ggH = base_objects.Process({ 'legs': qqx_to_ggH_legs, 'model': simple_qcd.model, 'n_loops': 0 }) # Test low-level approach limit #===================================================================================== def test_low_level_approach_limit(self): K = subtraction.SingularStructure C = subtraction.CollStructure S = subtraction.SoftStructure def L(n, state=FINAL): return subtraction.SubtractionLeg(n, 0, state) limit1 = [( walkers.mappings.FinalGroupingMapping, K(C(L(3), L(4)), L(2), L(5), L(6)), 0., ), ( walkers.mappings.FinalGroupingMapping, K(C(L(5), L(9)), L(2), L(6)), 1., )] self._test_low_level_approach_limit(self.H_to_bbxuuxggg, limit1) # Test NLO walkers #===================================================================================== def test_FinalRescalingNLOWalker_approach_limit(self): walker = walkers.FinalRescalingNLOWalker() self._test_approach_limit(walker, self.H_to_uuxddx, 1, 1) self._test_approach_limit(walker, self.H_to_uuxddxg, 1, 1) self._test_approach_limit(walker, self.H_to_uuxddxH, 1, 1) self._test_approach_limit(walker, self.H_to_qqxggH, 1, 1) def test_FinalLorentzNLOWalker_approach_limit(self): walker = walkers.FinalLorentzNLOWalker() self._test_approach_limit(walker, self.H_to_uuxddxH, 1, 1) self._test_approach_limit(walker, self.H_to_qqxggH, 1, 1) def test_LorentzNLOWalker_approach_limit(self): walker = walkers.LorentzNLOWalker() self._test_approach_limit(walker, self.H_to_uuxddxg, 1, 1) # The following fails because the soft mapping does not handle massive particles # self._test_approach_limit(walker, self.H_to_uuxddxH, 1, 1) # self._test_approach_limit(walker, self.H_to_qqxggH, 1, 1) # self._test_approach_limit(walker, self.qqx_to_ggH, 1, 1) def test_SoftBeamsRecoilNLOWalker_approach_limit(self): walker = walkers.SoftBeamsRecoilNLOWalker() self._test_approach_limit(walker, self.H_to_qqxggH, 1, 1) self._test_approach_limit(walker, self.qqx_to_ggH, 1, 1)
def test_run_python_matrix_element(self): """Test a complete running of a Python matrix element without writing any files""" # Import the SM sm_path = import_ufo.find_ufo_path('sm') model = import_ufo.import_model(sm_path) myleglist = base_objects.LegList() myleglist.append( base_objects.Leg({ 'id': -11, 'state': False, 'number': 1 })) myleglist.append( base_objects.Leg({ 'id': 11, 'state': False, 'number': 2 })) myleglist.append( base_objects.Leg({ 'id': 22, 'state': True, 'number': 3 })) myleglist.append( base_objects.Leg({ 'id': 22, 'state': True, 'number': 4 })) myleglist.append( base_objects.Leg({ 'id': 22, 'state': True, 'number': 5 })) myproc = base_objects.Process({'legs': myleglist, 'model': model}) myamplitude = diagram_generation.Amplitude({'process': myproc}) mymatrixelement = helas_objects.HelasMatrixElement(myamplitude) # Create only the needed aloha routines wanted_lorentz = mymatrixelement.get_used_lorentz() aloha_model = create_aloha.AbstractALOHAModel(model.get('name')) aloha_model.compute_subset(wanted_lorentz) # Write out the routines in Python aloha_routines = [] for routine in aloha_model.values(): aloha_routines.append(routine.write(output_dir = None, language = 'Python').\ replace('import wavefunctions', 'import aloha.template_files.wavefunctions as wavefunctions')) # Define the routines to be available globally for routine in aloha_routines: exec(routine, globals()) # Write the matrix element(s) in Python mypythonmodel = helas_call_writers.PythonUFOHelasCallWriter(\ model) exporter = export_python.ProcessExporterPython(\ mymatrixelement, mypythonmodel) matrix_methods = exporter.get_python_matrix_methods() # Calculate parameters and couplings full_model = model_reader.ModelReader(model) full_model.set_parameters_and_couplings() # Define a momentum p = [[ 0.5000000e+03, 0.0000000e+00, 0.0000000e+00, 0.5000000e+03, 0.0000000e+00 ], [ 0.5000000e+03, 0.0000000e+00, 0.0000000e+00, -0.5000000e+03, 0.0000000e+00 ], [ 0.4585788e+03, 0.1694532e+03, 0.3796537e+03, -0.1935025e+03, 0.6607249e-05 ], [ 0.3640666e+03, -0.1832987e+02, -0.3477043e+03, 0.1063496e+03, 0.7979012e-05 ], [ 0.1773546e+03, -0.1511234e+03, -0.3194936e+02, 0.8715287e+02, 0.1348699e-05 ]] # Evaluate the matrix element for the given momenta answer = 1.39189717257175028e-007 for process in matrix_methods.keys(): # Define Python matrix element for process exec(matrix_methods[process]) # Calculate the matrix element for the momentum p value = eval("Matrix_0_epem_aaa().smatrix(p, full_model)") self.assertTrue(abs(value-answer)/answer < 1e-6, "Value is: %.9e should be %.9e" % \ (abs(value), answer))
def testIO_Loop_sqso_uux_ddx(self): """ target: [loop_matrix(.*)\.f] """ myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id': 2, 'state': False})) myleglist.append(base_objects.Leg({'id': -2, 'state': False})) myleglist.append(base_objects.Leg({'id': 1, 'state': True})) myleglist.append(base_objects.Leg({'id': -1, 'state': True})) fortran_model=\ helas_call_writers.FortranUFOHelasCallWriterOptimized(self.model,False) SO_tests = [({}, ['QCD', 'QED'], {}, {}, ['QCD', 'QED'], 'QCDQEDpert_default'), ({}, ['QCD'], {}, {}, ['QCD'], 'QCDpert_default'), ({}, ['QED'], {}, {}, ['QED'], 'QEDpert_default'), ({}, ['QCD', 'QED'], { 'QCD': 4 }, { 'QCD': '==' }, ['QCD', 'QED'], 'QCDQEDpert_QCDsq_eq_4'), ({}, ['QCD', 'QED'], { 'QED': 4 }, { 'QCD': '<=' }, ['QCD', 'QED'], 'QCDQEDpert_QEDsq_le_4'), ({}, ['QCD', 'QED'], { 'QCD': 4 }, { 'QCD': '>' }, ['QCD', 'QED'], 'QCDQEDpert_QCDsq_gt_4'), ({ 'QED': 2 }, ['QCD', 'QED'], { 'QCD': 0, 'QED': 2 }, { 'QCD': '>', 'QED': '>' }, ['QCD', 'QED'], 'QCDQEDpert_QCDsq_gt_0_QEDAmpAndQEDsq_gt_2'), ({ 'QED': 2 }, ['QCD', 'QED'], { 'WEIGHTED': 10, 'QED': 2 }, { 'WEIGHTED': '<=', 'QED': '>' }, ['WEIGHTED', 'QCD', 'QED'], 'QCDQEDpert_WGTsq_le_10_QEDAmpAndQEDsq_gt_2')] for orders, pert_orders, sq_orders , sq_orders_type, split_orders, name \ in SO_tests: myproc = base_objects.Process({ 'legs': myleglist, 'model': self.model, 'orders': orders, 'squared_orders': sq_orders, 'perturbation_couplings': pert_orders, 'sqorders_types': sq_orders_type, 'split_orders': split_orders }) myloopamp = loop_diagram_generation.LoopAmplitude(myproc) matrix_element=loop_helas_objects.LoopHelasMatrixElement(\ myloopamp,optimized_output=True) writer = writers.FortranWriter(\ pjoin(self.IOpath,'loop_matrix_%s.f'%name)) # It is enough here to generate and check the filer loop_matrix.f # only here. For that we must initialize the general replacement # dictionary first (The four functions below are normally directly # called from the write_matrix_element function in the exporter # [but we don't call it here because we only want the file # loop_matrix.f]). matrix_element.rep_dict = self.exporter.\ generate_general_replace_dict(matrix_element) # and for the same reason also force the computation of the analytical # information in the Helas loop diagrams. matrix_element.compute_all_analytic_information( self.exporter.get_aloha_model(self.model)) # Finally the entries specific to the optimized output self.exporter.set_optimized_output_specific_replace_dict_entries(\ matrix_element) # We can then finally write out 'loop_matrix.f' self.exporter.write_loopmatrix(writer, matrix_element, fortran_model, noSplit=True, write_auxiliary_files=False)
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 find_symmetry_by_evaluation(matrix_element, evaluator, max_time=600): """Find symmetries between amplitudes by comparing the squared amplitudes for all permutations of identical particles. Return list of positive number corresponding to number of symmetric diagrams and negative numbers corresponding to the equivalent diagram (for e+e->3a, get [6, -1, -1, -1, -1, -1]), list of the corresponding permutations needed, and list of all permutations of identical particles. max_time gives a cutoff time for finding symmetries (in s).""" #if isinstance(matrix_element, group_subprocs.SubProcessGroup): # return find_symmetry_subproc_group(matrix_element, evaluator, max_time) assert isinstance(matrix_element, helas_objects.HelasMatrixElement) # Exception class and routine to handle timeout class TimeOutError(Exception): pass def handle_alarm(signum, frame): raise TimeOutError (nexternal, ninitial) = matrix_element.get_nexternal_ninitial() # Prepare the symmetry vector with non-used amp2s (due to # multiparticle vertices) symmetry = [] for diag in matrix_element.get('diagrams'): if max(diag.get_vertex_leg_numbers()) > 3: # Ignore any diagrams with 4-particle vertices symmetry.append(0) else: symmetry.append(1) # Check for matrix elements with no identical particles if matrix_element.get("identical_particle_factor") == 1: return symmetry, \ [range(nexternal)]*len(symmetry),\ [range(nexternal)] logger.info("Finding symmetric diagrams for process %s" % \ matrix_element.get('processes')[0].nice_string().\ replace("Process: ", "")) process = matrix_element.get('processes')[0] base_model = process.get('model') equivalent_process = base_objects.Process({\ 'legs': base_objects.LegList([base_objects.Leg({ 'id': wf.get('pdg_code'), 'state': wf.get('leg_state')}) \ for wf in matrix_element.get_external_wavefunctions()]), 'model': base_model}) # Get phase space point p, w_rambo = evaluator.get_momenta(equivalent_process) # Check matrix element value for all permutations amp2start = [] final_states = [l.get('id') for l in \ equivalent_process.get('legs')[ninitial:]] nperm = 0 perms = [] ident_perms = [] # Set timeout for max_time signal.signal(signal.SIGALRM, handle_alarm) signal.alarm(max_time) try: for perm in itertools.permutations(range(ninitial, nexternal)): if [equivalent_process.get('legs')[i].get('id') for i in perm] != \ final_states: # Non-identical particles permutated continue ident_perms.append([0, 1] + list(perm)) nperm += 1 new_p = p[:ninitial] + [p[i] for i in perm] res = evaluator.evaluate_matrix_element(matrix_element, new_p) if not res: break me_value, amp2 = res # Make a list with (8-pos value, magnitude) to easily compare amp2sum = sum(amp2) amp2mag = [] for a in amp2: a = a * me_value / max(amp2sum, 1e-30) if a > 0: amp2mag.append(int(math.floor(math.log10(abs(a))))) else: amp2mag.append(0) amp2 = [(int(a * 10**(8 - am)), am) for (a, am) in zip(amp2, amp2mag)] if not perms: # This is the first iteration - initialize lists # Initiate symmetry with all 1:s symmetry = [1 for i in range(len(amp2))] # Store initial amplitudes amp2start = amp2 # Initialize list of permutations perms = [range(nexternal) for i in range(len(amp2))] continue for i, val in enumerate(amp2): if val == (0, 0): # If amp2 is 0, just set symmetry to 0 symmetry[i] = 0 continue # Only compare with diagrams below this one if val in amp2start[:i]: ind = amp2start.index(val) # Replace if 1) this amp is unmatched (symmetry[i] > 0) or # 2) this amp is matched but matched to an amp larger # than ind if symmetry[ind] > 0 and \ (symmetry[i] > 0 or \ symmetry[i] < 0 and -symmetry[i] > ind + 1): symmetry[i] = -(ind + 1) perms[i] = [0, 1] + list(perm) symmetry[ind] += 1 except TimeOutError: # Symmetry canceled due to time limit logger.warning("Cancel diagram symmetry - time exceeded") # Stop the alarm since we're done with this process signal.alarm(0) return (symmetry, perms, ident_perms)
def setUp(self): # Set up model mypartlist = base_objects.ParticleList() myinterlist = base_objects.InteractionList() # u and c quarkd and their antiparticles 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[len(mypartlist) - 1] antiu = copy.copy(u) antiu.set('is_part', False) mypartlist.append( base_objects.Particle({ 'name': 'c', 'antiname': 'c~', 'spin': 2, 'color': 3, 'mass': 'MC', 'width': 'ZERO', 'texname': 'c', 'antitexname': '\bar c', 'line': 'straight', 'charge': 2. / 3., 'pdg_code': 4, 'propagating': True, 'is_part': True, 'self_antipart': False })) c = mypartlist[len(mypartlist) - 1] antic = copy.copy(c) antic.set('is_part', False) # A gluon mypartlist.append( base_objects.Particle({ 'name': 'g', 'antiname': 'g', 'spin': 3, 'color': 8, 'mass': 'ZERO', 'width': 'ZERO', 'texname': 'g', 'antitexname': 'g', 'line': 'curly', 'charge': 0., 'pdg_code': 21, 'propagating': True, 'is_part': True, 'self_antipart': True })) g = mypartlist[len(mypartlist) - 1] # A photon 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[len(mypartlist) - 1] # Gluon couplings to quarks myinterlist.append(base_objects.Interaction({ 'id': 1, 'particles': base_objects.ParticleList(\ [antiu, \ u, \ g]), 'color': [color.ColorString([color.T(2, 1, 0)])], 'lorentz':['FFV1'], 'couplings':{(0, 0):'GC_10'}, 'orders':{'QCD':1}})) # Gamma couplings to quarks myinterlist.append(base_objects.Interaction({ 'id': 2, 'particles': base_objects.ParticleList(\ [antiu, \ u, \ z]), 'color': [color.ColorString([color.T(1, 0)])], 'lorentz':['FFV2', 'FFV5'], 'couplings':{(0,0): 'GC_35', (0,1): 'GC_47'}, 'orders':{'QED':1}})) self.mymodel.set('particles', mypartlist) self.mymodel.set('interactions', myinterlist) self.mymodel.set('name', 'sm') self.mypythonmodel = helas_call_writers.PythonUFOHelasCallWriter( self.mymodel) myleglist = base_objects.LegList() myleglist.append(base_objects.Leg({'id': 2, 'state': False})) myleglist.append(base_objects.Leg({'id': -2, 'state': False})) myleglist.append(base_objects.Leg({'id': 2, 'state': True})) myleglist.append(base_objects.Leg({'id': -2, 'state': True})) myproc = base_objects.Process({ 'legs': myleglist, 'model': self.mymodel }) myamplitude = diagram_generation.Amplitude({'process': myproc}) self.mymatrixelement = helas_objects.HelasMultiProcess(myamplitude) myleglist = base_objects.LegList() myleglist.append( base_objects.Leg({ 'id': 4, 'state': False, 'number': 1 })) myleglist.append( base_objects.Leg({ 'id': -4, 'state': False, 'number': 2 })) myleglist.append( base_objects.Leg({ 'id': 4, 'state': True, 'number': 3 })) myleglist.append( base_objects.Leg({ 'id': -4, 'state': True, 'number': 4 })) myproc = base_objects.Process({ 'legs': myleglist, 'model': self.mymodel }) self.mymatrixelement.get('matrix_elements')[0].\ get('processes').append(myproc) self.exporter = export_python.ProcessExporterPython(\ self.mymatrixelement, self.mypythonmodel)