def test_lhe_none_decay(self): """ """ cwd = os.getcwd() files.cp( pjoin(MG5DIR, 'tests', 'input_files', 'test_spinmode_none.lhe.gz'), self.path) fsock = open(pjoin(self.path, 'test_hepmc'), 'w') text = """ set spinmode none import ./test_spinmode_none.lhe.gz decay z > mu+ mu- launch """ fsock.write(text) fsock.close() import subprocess if logging.getLogger('madgraph').level <= 20: stdout = None stderr = None else: devnull = open(os.devnull, 'w') stdout = devnull stderr = devnull subprocess.call([ pjoin(MG5DIR, 'MadSpin', 'madspin'), pjoin(self.path, 'test_hepmc') ], cwd=pjoin(self.path), stdout=stdout, stderr=stderr) self.assertTrue( os.path.exists( pjoin(self.path, 'test_spinmode_none_decayed.lhe.gz'))) lhe = lhe_parser.EventFile( pjoin(self.path, 'test_spinmode_none_decayed.lhe.gz')) self.assertEqual(100, len(lhe)) nb_dec = 0 nb_muon = 0 for event in lhe: muon_in = 0 self.assertEqual(event.nexternal, len(event)) for particle in event: if particle.pdg == 23: self.assertEqual(particle.status, 2) nb_dec += 1 if particle.pdg == 13: nb_muon += 1 muon_in += 1 self.assertEqual(muon_in, 1) self.assertEqual(nb_dec, 189) self.assertEqual(nb_muon, 100)
def test_hepmc_decay(self): """ """ cwd = os.getcwd() files.cp(pjoin(MG5DIR, 'tests', 'input_files', 'test.hepmc.gz'), self.path) fsock = open(pjoin(self.path, 'test_hepmc'), 'w') text = """ set spinmode none set cross_section {0:1.0} set new_wgt BR set input_format hepmc import ./test.hepmc.gz import model %s/tests/input_files/DM_pion %s/tests/input_files/DM_pion/param_pion.dat decay k0 > xr xr a launch """ % (MG5DIR, MG5DIR) fsock.write(text) fsock.close() import subprocess if logging.getLogger('madgraph').level <= 20: stdout = None stderr = None else: devnull = open(os.devnull, 'w') stdout = devnull stderr = devnull subprocess.call([ pjoin(MG5DIR, 'MadSpin', 'madspin'), pjoin(self.path, 'test_hepmc') ], cwd=pjoin(self.path), stdout=stdout, stderr=stdout) self.assertTrue(os.path.exists(pjoin(self.path, 'test_decayed.lhe.gz'))) lhe = lhe_parser.EventFile(pjoin(self.path, 'test_decayed.lhe.gz')) self.assertEqual(10, len(lhe)) nb_dec = 0 nb_photon = 0 for event in lhe: self.assertEqual(event.nexternal, len(event)) for particle in event: if particle.pdg == 130: self.assertEqual(particle.status, 2) nb_dec += 1 if particle.pdg == 22: nb_photon += 1 self.assertEqual(nb_dec, 116) self.assertEqual(nb_photon, 116)
def do_import(self, inputfile): """import the event file""" # change directory where to write the output self.options['curr_dir'] = os.path.realpath(os.path.dirname(inputfile)) if os.path.basename(os.path.dirname(os.path.dirname(inputfile))) == 'Events': self.options['curr_dir'] = pjoin(self.options['curr_dir'], os.path.pardir, os.pardir) if not os.path.exists(inputfile): if inputfile.endswith('.gz'): if not os.path.exists(inputfile[:-3]): raise self.InvalidCmd('No such file or directory : %s' % inputfile) else: inputfile = inputfile[:-3] elif os.path.exists(inputfile + '.gz'): inputfile = inputfile + '.gz' else: raise self.InvalidCmd('No such file or directory : %s' % inputfile) if inputfile.endswith('.gz'): misc.gunzip(inputfile) inputfile = inputfile[:-3] # Read the banner of the inputfile self.lhe_input = lhe_parser.EventFile(os.path.realpath(inputfile)) if not self.lhe_input.banner: value = self.ask("What is the path to banner", 0, [0], "please enter a path", timeout=0) self.lhe_input.banner = open(value).read() self.banner = self.lhe_input.get_banner() # Check the validity of the banner: if 'slha' not in self.banner: self.events_file = None raise self.InvalidCmd('Event file does not contain model information') elif 'mg5proccard' not in self.banner: self.events_file = None raise self.InvalidCmd('Event file does not contain generation information') if 'madspin' in self.banner: raise self.InvalidCmd('Reweight should be done before running MadSpin') # load information process = self.banner.get_detail('proc_card', 'generate') if '[' in process: msg = 'Reweighting options is valid only for LO events' raise Exception, msg if not process: msg = 'Invalid proc_card information in the file (no generate line):\n %s' % self.banner['mg5proccard'] raise Exception, msg process, option = mg_interface.MadGraphCmd.split_process_line(process) self.proc_option = option logger.info("process: %s" % process) logger.info("options: %s" % option)
class TestMEfromfile(unittest.TestCase): """test that we can launch everything from a single file""" def setUp(self): self.debuging = False if self.debuging: self.path = pjoin(MG5DIR, 'ACC_TEST') if os.path.exists(self.path): shutil.rmtree(self.path) os.mkdir(self.path) else: self.path = tempfile.mkdtemp(prefix='acc_test_mg5') self.run_dir = pjoin(self.path, 'MGPROC') def tearDown(self): if not self.debuging: shutil.rmtree(self.path) def test_add_time_of_flight(self): """checking time of flight is working fine""" if logging.getLogger('madgraph').level <= 20: stdout = None stderr = None else: devnull = open(os.devnull, 'w') stdout = devnull stderr = devnull if not os.path.exists(pjoin(MG5DIR, 'pythia-pgs')): p = subprocess.Popen([pjoin(MG5DIR, 'bin', 'mg5')], stdin=subprocess.PIPE, stdout=stdout, stderr=stderr) out = p.communicate('install pythia-pgs') misc.compile(cwd=pjoin(MG5DIR, 'pythia-pgs')) try: shutil.rmtree('/tmp/MGPROCESS/') except Exception, error: pass cmd = """import model sm set automatic_html_opening False --no_save set notification_center False --no_save generate p p > w+ z output %s -f -nojpeg launch -i set automatic_html_opening False --no_save generate_events parton set nevents 100 set event_norm sum set systematics_program none add_time_of_flight --threshold=4e-14 pythia """ % self.run_dir open(pjoin(self.path, 'mg5_cmd'), 'w').write(cmd) if logging.getLogger('madgraph').level <= 20: stdout = None stderr = None else: devnull = open(os.devnull, 'w') stdout = devnull stderr = devnull subprocess.call( [ pjoin(_file_path, os.path.pardir, 'bin', 'mg5'), pjoin(self.path, 'mg5_cmd') ], #cwd=self.path, stdout=stdout, stderr=stderr) self.check_parton_output(cross=15.62, error=0.19) self.check_pythia_output() event = '%s/Events/run_01/unweighted_events.lhe' % self.run_dir if not os.path.exists(event): misc.gunzip(event) has_zero = False has_non_zero = False for event in lhe_parser.EventFile(event): for particle in event: if particle.pid in [23, 25]: self.assertTrue(particle.vtim == 0 or particle.vtim > 4e-14) if particle.vtim == 0: has_zero = True else: has_non_zero = True self.assertTrue(has_zero) self.assertTrue(has_non_zero) self.assertFalse(self.debuging)
def test_madevent_ptj_bias(self): """ Test that biasing LO event generation works as intended. """ self.out_dir = self.run_dir if not self.debugging or not os.path.isdir( pjoin(MG5DIR, 'BackUp_tmp_test')): self.generate('d d~ > u u~', 'sm') run_card = banner.RunCardLO( pjoin(self.out_dir, 'Cards', 'run_card.dat')) run_card.set('bias_module', 'ptj_bias', user=True) run_card.set( 'bias_parameters', "{'ptj_bias_target_ptj': 1000.0,'ptj_bias_enhancement_power': 4.0}", user=True) run_card.set('use_syst', False) run_card.set('nevents', 10000) run_card.write(pjoin(self.out_dir, 'Cards', 'run_card.dat')) self.do('launch -f') run_card = banner.RunCardLO( pjoin(self.out_dir, 'Cards', 'run_card.dat')) run_card.set('bias_module', 'dummy', user=True) run_card.set('bias_parameters', "{}", user=True) run_card.set('use_syst', False) run_card.set('nevents', 10000) run_card.write(pjoin(self.out_dir, 'Cards', 'run_card.dat')) self.do('launch -f') if self.debugging: if os.path.isdir(pjoin(MG5DIR, 'BackUp_tmp_test')): shutil.rmtree(pjoin(MG5DIR, 'BackUp_tmp_test')) shutil.copytree(pjoin(MG5DIR, 'tmp_test'), pjoin(MG5DIR, 'BackUp_tmp_test')) else: shutil.rmtree(pjoin(MG5DIR, 'tmp_test')) shutil.copytree(pjoin(MG5DIR, 'BackUp_tmp_test'), pjoin(MG5DIR, 'tmp_test')) biased_events = lhe_parser.EventFile( pjoin(self.out_dir, 'Events', 'run_01', 'unweighted_events.lhe.gz')) unbiased_events = lhe_parser.EventFile( pjoin(self.out_dir, 'Events', 'run_02', 'unweighted_events.lhe.gz')) biased_events_ptj = [] biased_events_wgts = [] for event in biased_events: biased_events_ptj.append(math.sqrt(event[2].px**2 + event[2].py**2)) biased_events_wgts.append(event.wgt) biased_median_ptj = sorted(biased_events_ptj)[len(biased_events_ptj) // 2] unbiased_events_ptj = [] for event in unbiased_events: unbiased_events_ptj.append( math.sqrt(event[2].px**2 + event[2].py**2)) unbiased_median_ptj = sorted(unbiased_events_ptj)[ len(unbiased_events_ptj) // 2] # Make that not all biased events have the same weights self.assertGreater(len(set(biased_events_wgts)), 1) # Make sure that there is significantly more events in the ptj tail self.assertGreater(biased_median_ptj, 5.0 * unbiased_median_ptj) # Make sure that the cross-section is close enough for the bias and unbiased samples self.assertLess((abs(biased_events.cross - unbiased_events.cross) / abs(unbiased_events.cross)), 0.03)
# # Additional test: Check that the banner of the run_02 include correctly # the ptheavy 50 information banner = banner_mod.Banner( pjoin(self.run_dir, 'Events', 'run_01', 'run_01_fermi_banner.txt')) run_card = banner.charge_card('run_card') self.assertEqual(run_card['ptheavy'], 0) banner = banner_mod.Banner( pjoin(self.run_dir, 'Events', 'run_02', 'run_02_fermi_banner.txt')) run_card = banner.charge_card('run_card') self.assertEqual(run_card['ptheavy'], 50) events = lhe_parser.EventFile( pjoin(self.run_dir, 'Events', 'run_02', 'unweighted_events.lhe.gz')) banner = banner_mod.Banner(events.banner) run_card = banner.charge_card('run_card') self.assertEqual(run_card['ptheavy'], 50) for event in events: event.check() def load_result(self, run_name): import madgraph.iolibs.save_load_object as save_load_object import madgraph.madevent.gen_crossxhtml as gen_crossxhtml result = save_load_object.load_from_file( pjoin(self.run_dir, 'HTML/results.pkl')) return result[run_name]
outPath = pjoin(os.path.dirname(os.path.realpath(eventFile)), '%s_rwgt.%s' % (evtFileName, evtFileExt)) i = 0 while os.path.exists(outPath): i = i + 1 if outSpecified and i == 1: logging.warning( "The chosen filename %s for the output already exists." % os.path.basename(outPath)) outPath = pjoin(os.path.dirname(os.path.realpath(eventFile)), '%s_rwgt_%i.%s' % (evtFileName, i, evtFileExt)) try: evtBanner = banner.Banner(eventFile) evtFile = lhe_parser.EventFile(eventFile) except: logging.error("Could not read event file %s." % eventFile) # Start by loading the model of the banner try: model_name = evtBanner.get_detail('model') model_name = model_name.split('-')[0] # For now use the model 'sm' no matter what since it is only used for the particle naming scheme model_name = 'sm' user_model = import_ufo.import_full_model( pjoin(proc_path, os.pardir, 'models', model_name)) except: logging.error("Could not load the model %s used for generating the event file"\ %evtBanner.get_detail('model')) exit()
def test_madspin_LOonly(self): text = """ set crash_on_error True generate p p > w+ [LOonly] output %s launch madspin=ON set nevents 10 decay w+ > e+ ve launch -i decay_events run_01 add madspin --replace_line="set spinmode.*" --after_line="banner" set spinmode=onshell """ % self.path interface = MGCmd.MasterCmd() interface.no_notification() open(pjoin(self.tmpdir, 'cmd'), 'w').write(text) interface.exec_cmd('import command %s' % pjoin(self.tmpdir, 'cmd')) # perform some basic check lhe_on = pjoin(self.path, 'Events', 'run_01_decayed_1', 'events.lhe.gz') lhe_onshell = pjoin(self.path, 'Events', 'run_01_decayed_2', 'events.lhe.gz') self.assertTrue(lhe_on) # check that each events has the decay ON mode nb_event = 0 for event in lhe_parser.EventFile(lhe_on): nb_event += 1 nb_final = 0 m_inv_w = 0 for p in event: if p.status == -1: continue elif p.status == 1: nb_final += 1 else: if p.pdg == 24: if m_inv_w != 0: self.assertTrue(False, 'two W') m_inv_w = p.mass self.assertTrue(30 < m_inv_w < 150) else: misc.sprint(p.pdg, p.status) self.assertTrue(False, 'not W decaying') self.assertTrue(nb_final in [2]) self.assertEqual(nb_event, 10) self.assertTrue(lhe_onshell) # check that each events has the decay ON mode nb_event = 0 for event in lhe_parser.EventFile(lhe_onshell): nb_event += 1 nb_final = 0 m_inv_w = 0 for p in event: if p.status == -1: continue elif p.status == 1: nb_final += 1 else: if p.pdg == 24: if m_inv_w != 0: self.assertTrue(False, 'two W') m_inv_w = p.mass self.assertTrue(80 < m_inv_w < 81) else: self.assertTrue(False, 'not W decaying') self.assertTrue(nb_final in [2]) self.assertEqual(nb_event, 10)
def do_launch(self, line): """end of the configuration launched the code""" args = self.split_arg(line) self.check_launch(args) model_line = self.banner.get('proc_card', 'full_model_line') if not self.has_standalone_dir: self.create_standalone_directory() ff = open(pjoin(self.me_dir, 'rw_me','Cards', 'param_card.dat'), 'w') ff.write(self.banner['slha']) ff.close() ff = open(pjoin(self.me_dir, 'rw_me','Cards', 'param_card_orig.dat'), 'w') ff.write(self.banner['slha']) ff.close() cmd = common_run_interface.CommonRunCmd.ask_edit_card_static(cards=['param_card.dat'], ask=self.ask, pwd=pjoin(self.me_dir,'rw_me')) new_card = open(pjoin(self.me_dir, 'rw_me', 'Cards', 'param_card.dat')).read() # Find new tag in the banner and add information if needed if 'initrwgt' in self.banner: if 'type=\'mg_reweighting\'' in self.banner['initrwgt']: blockpat = re.compile(r'''<weightgroup type=\'mg_reweighting\'\s*>(?P<text>.*?)</weightgroup>''', re.I+re.M+re.S) before, content, after = blockpat.split(self.banner['initrwgt']) header_rwgt_other = before + after pattern = re.compile('<weight id=\'mg_reweight_(?P<id>\d+)\'>(?P<info>[^<>]*)</weight>', re.S+re.I+re.M) mg_rwgt_info = pattern.findall(content) maxid = 0 for i, diff in mg_rwgt_info: if int(i) > maxid: maxid = int(i) maxid += 1 rewgtid = maxid else: header_rwgt_other = self.banner['initrwgt'] mg_rwgt_info = [] rewgtid = 1 else: self.banner['initrwgt'] = '' header_rwgt_other = '' mg_rwgt_info = [] rewgtid = 1 # add the reweighting in the banner information: #starts by computing the difference in the cards. s_orig = self.banner['slha'] s_new = new_card old_param = check_param_card.ParamCard(s_orig.splitlines()) new_param = check_param_card.ParamCard(s_new.splitlines()) card_diff = old_param.create_diff(new_param) if card_diff == '': raise self.InvalidCmd, 'original card and new card are identical' mg_rwgt_info.append((str(rewgtid), card_diff)) # re-create the banner. self.banner['initrwgt'] = header_rwgt_other self.banner['initrwgt'] += '\n<weightgroup type=\'mg_reweighting\'>\n' for tag, diff in mg_rwgt_info: self.banner['initrwgt'] += '<weight id=\'mg_reweight_%s\'>%s</weight>\n' % \ (tag, diff) self.banner['initrwgt'] += '\n</weightgroup>\n' self.banner['initrwgt'] = self.banner['initrwgt'].replace('\n\n', '\n') output = open( self.lhe_input.name +'rw', 'w') logger.info('starts to compute weight for events with the following modification to the param_card:') logger.info(card_diff) #write the banner to the output file self.banner.write(output, close_tag=False) # prepare the output file for the weight plot if self.mother: out_path = pjoin(self.mother.me_dir, 'Events', 'reweight.lhe') output2 = open(out_path, 'w') self.banner.write(output2, close_tag=False) new_banner = banner.Banner(self.banner) if not hasattr(self, 'run_card'): self.run_card = new_banner.charge_card('run_card') self.run_card['run_tag'] = 'reweight_%s' % rewgtid new_banner['slha'] = s_new del new_banner['initrwgt'] #ensure that original banner is kept untouched assert new_banner['slha'] != self.banner['slha'] assert 'initrwgt' in self.banner ff = open(pjoin(self.mother.me_dir,'Events',self.mother.run_name, '%s_%s_banner.txt' % \ (self.mother.run_name, self.run_card['run_tag'])),'w') new_banner.write(ff) ff.close() # Loop over all events tag_name = 'mg_reweight_%s' % rewgtid start = time.time() cross = 0 os.environ['GFORTRAN_UNBUFFERED_ALL'] = 'y' if self.lhe_input.closed: self.lhe_input = lhe_parser.EventFile(self.lhe_input.name) for event_nb,event in enumerate(self.lhe_input): #control logger if (event_nb % max(int(10**int(math.log10(float(event_nb)+1))),1000)==0): running_time = misc.format_timer(time.time()-start) logger.info('Event nb %s %s' % (event_nb, running_time)) if (event_nb==10001): logger.info('reducing number of print status. Next status update in 10000 events') weight = self.calculate_weight(event) cross += weight event.reweight_data[tag_name] = weight #write this event with weight output.write(str(event)) if self.mother: event.wgt = weight event.reweight_data = {} output2.write(str(event)) running_time = misc.format_timer(time.time()-start) logger.info('All event done (nb_event: %s) %s' % (event_nb+1, running_time)) output.write('</LesHouchesEvents>\n') output.close() os.environ['GFORTRAN_UNBUFFERED_ALL'] = 'n' if self.mother: output2.write('</LesHouchesEvents>\n') output2.close() # add output information if hasattr(self.mother, 'results'): run_name = self.mother.run_name results = self.mother.results results.add_run(run_name, self.run_card, current=True) results.add_detail('nb_event', event_nb+1) results.add_detail('cross', cross) results.add_detail('error', 'nan') self.mother.create_plot(mode='reweight', event_path=output2.name, tag=self.run_card['run_tag']) #modify the html output to add the original run if 'plot' in results.current.reweight: html_dir = pjoin(self.mother.me_dir, 'HTML', run_name) td = pjoin(self.mother.options['td_path'], 'td') MA = pjoin(self.mother.options['madanalysis_path']) path1 = pjoin(html_dir, 'plots_parton') path2 = pjoin(html_dir, 'plots_%s' % self.run_card['run_tag']) outputplot = path2 combine_plots.merge_all_plots(path2, path1, outputplot, td, MA) #results.update_status(level='reweight') #results.update(status, level, makehtml=True, error=False) #old_name = self.mother.results.current['run_name'] #new_run = '%s_rw_%s' % (old_name, rewgtid) #self.mother.results.add_run( new_run, self.run_card) #self.mother.results.add_detail('nb_event', event_nb+1) #self.mother.results.add_detail('cross', cross) #self.mother.results.add_detail('error', 'nan') #self.mother.do_plot('%s -f' % new_run) #self.mother.update_status('Reweight %s done' % rewgtid, 'madspin') #self.mother.results.def_current(old_name) #self.run_card['run_tag'] = self.run_card['run_tag'][9:] #self.mother.run_name = old_name self.lhe_input.close() files.mv(output.name, self.lhe_input.name) logger.info('Event %s have now the additional weight' % self.lhe_input.name) logger.info('new cross-section is : %g pb' % cross) self.terminate_fortran_executables(new_card_only=True) #store result self.all_cross_section[rewgtid] = cross
def generate_events(pdg, nb_event, mg5, restrict_file=None, cumul=False): """generate new events for this particle restrict_file allow to only generate a subset of the definition cumul allow to merge all the definition in one run (add process) to generate events according to cross-section """ part = self.model.get_particle(pdg) name = part.get_name() out = {} logger.info("generate %s decay event for particle %s" % (nb_event, name)) if name not in self.list_branches: return out for i, proc in enumerate(self.list_branches[name]): if restrict_file and i not in restrict_file: continue decay_dir = pjoin( self.path_me, "decay_%s_%s" % (str(pdg).replace("-", "x"), i)) if not os.path.exists(decay_dir): if cumul: mg5.exec_cmd("generate %s" % proc) for j, proc2 in enumerate( self.list_branches[name][1:]): if restrict_file and j not in restrict_file: raise Exception # Do not see how this can happen mg5.exec_cmd("add process %s" % proc2) mg5.exec_cmd("output %s -f" % decay_dir) else: mg5.exec_cmd("generate %s" % proc) mg5.exec_cmd("output %s -f" % decay_dir) options = dict(mg5.options) if self.options['ms_dir']: misc.sprint("start gridpack!") # we are in gridpack mode -> create it me5_cmd = madevent_interface.MadEventCmdShell(me_dir=os.path.realpath(\ decay_dir), options=options) me5_cmd.options["automatic_html_opening"] = False if self.options["run_card"]: run_card = self.options["run_card"] else: run_card = banner.RunCard( pjoin(decay_dir, "Cards", "run_card.dat")) run_card["iseed"] = self.seed run_card['gridpack'] = True run_card.write( pjoin(decay_dir, "Cards", "run_card.dat")) param_card = self.banner['slha'] open(pjoin(decay_dir, "Cards", "param_card.dat"), "w").write(param_card) self.seed += 1 # actually creation me5_cmd.exec_cmd("generate_events run_01 -f") me5_cmd.exec_cmd("exit") #remove pointless informat misc.call( ["rm", "Cards", "bin", 'Source', 'SubProcesses'], cwd=decay_dir) misc.call(['tar', '-xzpvf', 'run_01_gridpack.tar.gz'], cwd=decay_dir) # Now generate the events if not self.options['ms_dir']: me5_cmd = madevent_interface.MadEventCmdShell(me_dir=os.path.realpath(\ decay_dir), options=mg5.options) me5_cmd.options["automatic_html_opening"] = False if self.options["run_card"]: run_card = self.options["run_card"] else: run_card = banner.RunCard( pjoin(decay_dir, "Cards", "run_card.dat")) run_card["nevents"] = int(1.2 * nb_event) run_card["iseed"] = self.seed run_card.write(pjoin(decay_dir, "Cards", "run_card.dat")) param_card = self.banner['slha'] open(pjoin(decay_dir, "Cards", "param_card.dat"), "w").write(param_card) self.seed += 1 me5_cmd.exec_cmd("generate_events run_01 -f") me5_cmd.exec_cmd("exit") out[i] = lhe_parser.EventFile( pjoin(decay_dir, "Events", 'run_01', 'unweighted_events.lhe.gz')) else: misc.call( ['run.sh', str(int(1.2 * nb_event)), str(self.seed)], cwd=decay_dir) out[i] = lhe_parser.EventFile( pjoin(decay_dir, 'events.lhe.gz')) if cumul: break return out
def test_madspin_ON_and_onshell_atNLO(self): nevents = 20 text = """ set crash_on_error True generate p p > t t~ [QCD] output %s launch madspin=ON shower=OFF set nevents %s set mt 174 set wt = 1.5 decay t > w+ b decay t~ > w- b~ launch -i decay_events run_01 add madspin --replace_line="set spinmode.*" --after_line=banner set spinmode=onshell """ % (self.path, nevents) interface = MGCmd.MasterCmd() interface.no_notification() open(pjoin(self.tmpdir, 'cmd'), 'w').write(text) interface.exec_cmd('import command %s' % pjoin(self.tmpdir, 'cmd')) # perform some basic check orig_lhe = pjoin(self.path, 'Events', 'run_01', 'events.lhe.gz') lhe_on = pjoin(self.path, 'Events', 'run_01_decayed_1', 'events.lhe.gz') lhe_onshell = pjoin(self.path, 'Events', 'run_01_decayed_2', 'events.lhe.gz') self.assertTrue(lhe_on) mt = 174 wt = 1.5 # check that original event has top onshell nb_event = 0 for event in lhe_parser.EventFile(orig_lhe): nb_event += 1 nb_final = 0 m_inv_t = 0 m_inv_tbar = 0 for p in event: if p.status == -1: continue elif p.status == 1: nb_final += 1 if p.pdg == 6: #if m_inv_t != 0: # self.assertTrue(False, 'two top decaying') m_inv_t = p.mass self.assertTrue( mt - 0.1 * wt < m_inv_t < mt + 0.1 * wt) elif p.pdg == -6: #if m_inv_t != 0: # self.assertTrue(False, 'two antitop decaying') m_inv_tbar = p.mass self.assertTrue( mt - 0.1 * wt < m_inv_tbar < mt + 0.1 * wt) #else: # self.assertTrue(False, 'not top-antitop decaying') self.assertTrue(nb_final in [2, 3]) self.assertEqual(nb_event, nevents) # check that each events has the decay ON mode nb_event = 0 for event in lhe_parser.EventFile(lhe_on): nb_event += 1 nb_final = 0 m_inv_t = 0 m_inv_tbar = 0 for p in event: if p.status == -1: continue elif p.status == 1: nb_final += 1 else: if p.pdg == 6: #if m_inv_t != 0: # self.assertTrue(False, 'two top decaying') m_inv_t = p.mass self.assertTrue(mt - 15 * wt < m_inv_t < mt + 15 * wt) elif p.pdg == -6: #if m_inv_t != 0: # self.assertTrue(False, 'two antitop decaying') m_inv_tbar = p.mass self.assertTrue( mt - 15 * wt < m_inv_tbar < mt + 15 * wt) else: self.assertTrue(False, 'not top-antitop decaying') self.assertTrue(nb_final in [4, 5]) self.assertEqual(nb_event, nevents) # check that each events has the decay ON mode nb_event = 0 for event in lhe_parser.EventFile(lhe_onshell): nb_event += 1 nb_final = 0 m_inv_t = 0 m_inv_tbar = 0 for p in event: if p.status == -1: continue elif p.status == 1: nb_final += 1 else: if p.pdg == 6: #if m_inv_t != 0: # self.assertTrue(False, 'two top decaying') m_inv_t = p.mass self.assertTrue(mt - 1 < m_inv_t < mt + 1) elif p.pdg == -6: #if m_inv_t != 0: # self.assertTrue(False, 'two antitop decaying') m_inv_tbar = p.mass self.assertTrue(mt - 1 < m_inv_tbar < mt + 1) else: self.assertTrue(False, 'not top-antitop decaying') self.assertTrue(nb_final in [4, 5]) self.assertEqual(nb_event, nevents)
def run_bridge(self, line): """Run the Bridge Algorithm""" # 1. Read the event file to check which decay to perform and the number # of event to generate for each type of particle. # 2. Generate the events requested # 3. perform the merge of the events. # if not enough events. re-generate the missing one. # First define an utility function for generating events when needed def generate_events(pdg, nb_event, mg5, restrict_file=None, cumul=False): """generate new events for this particle restrict_file allow to only generate a subset of the definition cumul allow to merge all the definition in one run (add process) to generate events according to cross-section """ part = self.model.get_particle(pdg) name = part.get_name() out = {} logger.info("generate %s decay event for particle %s" % (nb_event, name)) if name not in self.list_branches: return out for i, proc in enumerate(self.list_branches[name]): if restrict_file and i not in restrict_file: continue decay_dir = pjoin( self.path_me, "decay_%s_%s" % (str(pdg).replace("-", "x"), i)) if not os.path.exists(decay_dir): if cumul: mg5.exec_cmd("generate %s" % proc) for j, proc2 in enumerate( self.list_branches[name][1:]): if restrict_file and j not in restrict_file: raise Exception # Do not see how this can happen mg5.exec_cmd("add process %s" % proc2) mg5.exec_cmd("output %s -f" % decay_dir) else: mg5.exec_cmd("generate %s" % proc) mg5.exec_cmd("output %s -f" % decay_dir) options = dict(mg5.options) if self.options['ms_dir']: misc.sprint("start gridpack!") # we are in gridpack mode -> create it me5_cmd = madevent_interface.MadEventCmdShell(me_dir=os.path.realpath(\ decay_dir), options=options) me5_cmd.options["automatic_html_opening"] = False if self.options["run_card"]: run_card = self.options["run_card"] else: run_card = banner.RunCard( pjoin(decay_dir, "Cards", "run_card.dat")) run_card["iseed"] = self.seed run_card['gridpack'] = True run_card.write( pjoin(decay_dir, "Cards", "run_card.dat")) param_card = self.banner['slha'] open(pjoin(decay_dir, "Cards", "param_card.dat"), "w").write(param_card) self.seed += 1 # actually creation me5_cmd.exec_cmd("generate_events run_01 -f") me5_cmd.exec_cmd("exit") #remove pointless informat misc.call( ["rm", "Cards", "bin", 'Source', 'SubProcesses'], cwd=decay_dir) misc.call(['tar', '-xzpvf', 'run_01_gridpack.tar.gz'], cwd=decay_dir) # Now generate the events if not self.options['ms_dir']: me5_cmd = madevent_interface.MadEventCmdShell(me_dir=os.path.realpath(\ decay_dir), options=mg5.options) me5_cmd.options["automatic_html_opening"] = False if self.options["run_card"]: run_card = self.options["run_card"] else: run_card = banner.RunCard( pjoin(decay_dir, "Cards", "run_card.dat")) run_card["nevents"] = int(1.2 * nb_event) run_card["iseed"] = self.seed run_card.write(pjoin(decay_dir, "Cards", "run_card.dat")) param_card = self.banner['slha'] open(pjoin(decay_dir, "Cards", "param_card.dat"), "w").write(param_card) self.seed += 1 me5_cmd.exec_cmd("generate_events run_01 -f") me5_cmd.exec_cmd("exit") out[i] = lhe_parser.EventFile( pjoin(decay_dir, "Events", 'run_01', 'unweighted_events.lhe.gz')) else: misc.call( ['run.sh', str(int(1.2 * nb_event)), str(self.seed)], cwd=decay_dir) out[i] = lhe_parser.EventFile( pjoin(decay_dir, 'events.lhe.gz')) if cumul: break return out args = self.split_arg(line) #0. Define the path where to write the file self.path_me = os.path.realpath(self.options['curr_dir']) if self.options['ms_dir']: self.path_me = os.path.realpath(self.options['ms_dir']) if not os.path.exists(self.path_me): os.mkdir(self.path_me) else: # cleaning for name in misc.glob("decay_*_*", self.path_me): shutil.rmtree(name) self.events_file.close() orig_lhe = lhe_parser.EventFile(self.events_file.name) to_decay = collections.defaultdict(int) nb_event = 0 for event in orig_lhe: nb_event += 1 for particle in event: if particle.status == 1 and particle.pdg in self.final_state: # final state and tag as to decay to_decay[particle.pdg] += 1 # Handle the banner of the output file if not self.seed: self.seed = random.randint(0, int(30081 * 30081)) self.do_set('seed %s' % self.seed) logger.info('Will use seed %s' % self.seed) self.history.insert(0, 'set seed %s' % self.seed) if self.seed > 30081 * 30081: # can't use too big random number msg = 'Random seed too large ' + str(self.seed) + ' > 30081*30081' raise Exception, msg self.options['seed'] = self.seed text = '%s\n' % '\n'.join([line for line in self.history if line]) self.banner.add_text('madspin', text) # 2. Generate the events requested with misc.MuteLogger(["madgraph", "madevent", "ALOHA", "cmdprint"], [50, 50, 50, 50]): mg5 = self.mg5cmd modelpath = self.model.get('modelpath+restriction') mg5.exec_cmd("import model %s" % modelpath) to_event = {} for pdg, nb_needed in to_decay.items(): #check if a splitting is needed if nb_needed == nb_event: to_event[pdg] = generate_events(pdg, nb_needed, mg5) elif nb_needed % nb_event == 0: nb_mult = nb_needed // nb_event part = self.model.get_particle(pdg) name = part.get_name() if name not in self.list_branches: continue elif len(self.list_branches[name]) == nb_mult: to_event[pdg] = generate_events(pdg, nb_event, mg5) else: to_event[pdg] = generate_events(pdg, nb_needed, mg5, cumul=True) else: part = self.model.get_particle(pdg) name = part.get_name() if name not in self.list_branches or len( self.list_branches[name]) == 0: continue raise self.InvalidCmd( "The bridge mode of MadSpin does not support event files where events do not *all* share the same set of final state particles to be decayed." ) # Compute the branching ratio. br = 1 for (pdg, event_files) in to_event.items(): if not event_files: continue totwidth = float(self.banner.get('param', 'decay', abs(pdg)).value) if to_decay[pdg] == nb_event: # Exactly one particle of this type to decay by event pwidth = sum([event_files[k].cross for k in event_files]) if pwidth > 1.01 * totwidth: logger.critical("Branching ratio larger than one for %s " % pdg) br *= pwidth / totwidth elif to_decay[pdg] % nb_event == 0: # More than one particle of this type to decay by event # Need to check the number of event file to check if we have to # make separate type of decay or not. nb_mult = to_decay[pdg] // nb_event if nb_mult == len(event_files): for k in event_files: pwidth = event_files[k].cross if pwidth > 1.01 * totwidth: logger.critical( "Branching ratio larger than one for %s " % pdg) br *= pwidth / totwidth br *= math.factorial(nb_mult) else: pwidth = sum(event_files[k].cross for k in event_files) if pwidth > 1.01 * totwidth: logger.critical( "Branching ratio larger than one for %s " % pdg) br *= (pwidth / totwidth)**nb_mult else: raise self.InvalidCmd( "The bridge mode of MadSpin does not support event files where events do not *all* share the same set of final state particles to be decayed." ) self.branching_ratio = br # modify the cross-section in the init block of the banner self.banner.scale_init_cross(self.branching_ratio) # 3. Merge the various file together. output_lhe = lhe_parser.EventFile( orig_lhe.name.replace('.lhe', '_decayed.lhe.gz'), 'w') self.banner.write(output_lhe, close_tag=False) # initialise object which store not use event due to wrong helicity bufferedEvents_decay = {} for pdg in to_event: bufferedEvents_decay[pdg] = [{}] * len(to_event[pdg]) import time start = time.time() counter = 0 orig_lhe.seek(0) for event in orig_lhe: if counter and counter % 1000 == 0 and float( str(counter)[1:]) == 0: print "decaying event number %s [%s s]" % (counter, time.time() - start) counter += 1 # use random order for particles to avoid systematics when more than # one type of decay is asked. particles = [p for p in event if int(p.status) == 1.0] random.shuffle(particles) ids = [particle.pid for particle in particles] for i, particle in enumerate(particles): # check if we need to decay the particle if particle.pdg not in self.final_state or particle.pdg not in to_event: continue # nothing to do for this particle # check how the decay need to be done nb_decay = len(to_event[particle.pdg]) if nb_decay == 0: continue #nothing to do for this particle if nb_decay == 1: decay_file = to_event[particle.pdg][0] decay_file_nb = 0 elif ids.count(particle.pdg) == nb_decay: decay_file = to_event[particle.pdg][ids[:i].count( particle.pdg)] decay_file_nb = ids[:i].count(particle.pdg) else: #need to select the file according to the associate cross-section r = random.random() tot = sum(to_event[particle.pdg][key].cross for key in to_event[particle.pdg]) r = r * tot cumul = 0 for j, events in to_event[particle.pdg].items(): cumul += events.cross if r < cumul: decay_file = events decay_file_nb = j else: break # ok start the procedure helicity = particle.helicity bufferedEvents = bufferedEvents_decay[ particle.pdg][decay_file_nb] # now that we have the file to read. find the associate event # checks if we have one event in memory if helicity in bufferedEvents and bufferedEvents[helicity]: decay = bufferedEvents[helicity].pop() else: # read the event file up to completion while 1: try: decay = decay_file.next() except StopIteration: # check how far we are ratio = counter / nb_event needed = 1.05 * to_decay[ particle.pdg] / ratio - counter needed = min(1000, max(needed, 1000)) with misc.MuteLogger( ["madgraph", "madevent", "ALOHA", "cmdprint"], [50, 50, 50, 50]): new_file = generate_events( particle.pdg, needed, mg5, [decay_file_nb]) to_event[particle.pdg].update(new_file) decay_file = to_event[particle.pdg][decay_file_nb] continue if helicity == decay[0].helicity or helicity==9 or \ self.options["spinmode"] == "none": break # use that event # not valid event store it for later if helicity not in bufferedEvents: bufferedEvents[helicity] = [decay] elif len(bufferedEvents[helicity]) < 200: # only add to the buffering if the buffer is not too large bufferedEvents[helicity].append(decay) # now that we have the event make the merge particle.add_decay(decay) # change the weight associate to the event event.wgt *= self.branching_ratio wgts = event.parse_reweight() for key in wgts: wgts[key] *= self.branching_ratio # all particle have been decay if needed output_lhe.write(str(event)) output_lhe.write('</LesHouchesEvent>\n')
def test_generation_from_file_1(self): """ """ cwd = os.getcwd() try: shutil.rmtree('/tmp/MGPROCESS/') except Exception as error: pass import subprocess if logging.getLogger('madgraph').level <= 20: stdout = None stderr = None else: devnull = open(os.devnull, 'w') stdout = devnull stderr = devnull if not os.path.exists(pjoin(MG5DIR, 'pythia-pgs')): p = subprocess.Popen([pjoin(MG5DIR, 'bin', 'mg5')], stdin=subprocess.PIPE, stdout=stdout, stderr=stderr) out = p.communicate('install pythia-pgs'.encode()) misc.compile(cwd=pjoin(MG5DIR, 'pythia-pgs')) if logging.getLogger('madgraph').level > 20: stdout = devnull else: stdout = None fsock = open(pjoin(self.path, 'test_mssm_generation'), 'w') fsock.write( open(pjoin(_file_path, 'input_files', 'test_mssm_generation')).read() % { 'dir_name': self.run_dir, 'mg5_path': pjoin(_file_path, os.path.pardir) }) fsock.close() subprocess.call( [ pjoin(_file_path, os.path.pardir, 'bin', 'mg5'), pjoin(self.path, 'test_mssm_generation') ], #cwd=pjoin(self.path), stdout=stdout, stderr=stdout) self.check_parton_output(cross=4.541638, error=0.035) self.check_parton_output('run_02', cross=4.41887317, error=0.035) self.check_pythia_output() self.assertEqual(cwd, os.getcwd()) # # Additional test: Check that the banner of the run_02 include correctly # the ptheavy 50 information banner = banner_mod.Banner( pjoin(self.run_dir, 'Events', 'run_01', 'run_01_fermi_banner.txt')) run_card = banner.charge_card('run_card') self.assertEqual(run_card['ptheavy'], 0) banner = banner_mod.Banner( pjoin(self.run_dir, 'Events', 'run_02', 'run_02_fermi_banner.txt')) run_card = banner.charge_card('run_card') self.assertEqual(run_card['ptheavy'], 50) events = lhe_parser.EventFile( pjoin(self.run_dir, 'Events', 'run_02', 'unweighted_events.lhe.gz')) banner = banner_mod.Banner(events.banner) run_card = banner.charge_card('run_card') self.assertEqual(run_card['ptheavy'], 50) for event in events: event.check()
def test_read_write_gzip(self): """ """ input = """<LesHouchesEvents version="1.0"> <header> DATA </header> <init> 2212 2212 0.70000000000E+04 0.70000000000E+04 0 0 10042 10042 3 1 0.16531958660E+02 0.18860728290E+00 0.17208000000E+00 0 </init> <event> 4 0 +1.7208000e-01 1.00890300e+02 7.95774700e-02 1.27947900e-01 -1 -1 0 0 0 501 +0.0000000e+00 +0.0000000e+00 +1.1943355e+01 1.19433546e+01 0.00000000e+00 0.0000e+00 1.0000e+00 2 -1 0 0 501 0 +0.0000000e+00 +0.0000000e+00 -1.0679326e+03 1.06793262e+03 0.00000000e+00 0.0000e+00 -1.0000e+00 24 1 1 2 0 0 +6.0417155e+00 +4.2744556e+01 -7.9238049e+02 7.97619997e+02 8.04190073e+01 3.4933e-25 -1.0000e+00 23 1 1 2 0 0 -6.0417155e+00 -4.2744556e+01 -2.6360878e+02 2.82255979e+02 9.11880035e+01 1.8975e-26 1.0000e+00 </event> <event> 4 0 +1.7208000e-01 1.00890300e+02 7.95774700e-02 1.27947900e-01 -1 -1 0 0 0 501 +0.0000000e+00 +0.0000000e+00 +1.1943355e+01 1.19433546e+01 0.00000000e+00 0.0000e+00 1.0000e+00 2 -1 0 0 501 0 +0.0000000e+00 +0.0000000e+00 -1.0679326e+03 1.06793262e+03 0.00000000e+00 0.0000e+00 -1.0000e+00 24 1 1 2 0 0 +6.0417155e+00 +4.2744556e+01 -7.9238049e+02 7.97619997e+02 8.04190073e+01 3.4933e-25 -1.0000e+00 23 1 1 2 0 0 -6.0417155e+00 -4.2744556e+01 -2.6360878e+02 2.82255979e+02 9.11880035e+01 1.8975e-26 1.0000e+00 # balbalblb #bbbb3 </event> <event> 7 66 +1.5024446e-03 3.15138740e+02 7.95774720e-02 9.66701260e-02 21 -1 0 0 502 501 +0.0000000e+00 +0.0000000e+00 -6.4150959e+01 6.41553430e+01 7.49996552e-01 0.0000e+00 0.0000e+00 2 -1 0 0 501 0 +0.0000000e+00 +0.0000000e+00 +8.1067989e+02 8.10679950e+02 3.11899968e-01 0.0000e+00 0.0000e+00 24 2 1 2 0 0 -1.5294533e+02 +1.0783429e+01 +4.5796553e+02 4.89600040e+02 8.04190039e+01 0.0000e+00 0.0000e+00 2 1 3 3 503 0 -1.5351296e+02 +1.2743130e+01 +4.6093709e+02 4.85995489e+02 0.00000000e+00 0.0000e+00 0.0000e+00 -1 1 3 3 0 503 +5.6763429e-01 -1.9597014e+00 -2.9715566e+00 3.60455091e+00 0.00000000e+00 0.0000e+00 0.0000e+00 23 1 1 2 0 0 +4.4740095e+01 +3.2658177e+01 +4.6168760e+01 1.16254200e+02 9.11880036e+01 0.0000e+00 0.0000e+00 1 1 1 2 502 0 +1.0820523e+02 -4.3441605e+01 +2.4239464e+02 2.68981060e+02 3.22945297e-01 0.0000e+00 0.0000e+00 # 2 5 2 2 1 0.11659994e+03 0.11659994e+03 8 0 0 0.10000000e+01 0.88172677e+00 0.11416728e+01 0.00000000e+00 0.00000000e+00 <rwgt> <wgt id='1001'> +9.1696000e+03 </wgt> <wgt id='1002'> +1.1264000e+04 </wgt> <wgt id='1003'> +6.9795000e+03 </wgt> <wgt id='1004'> +9.1513000e+03 </wgt> <wgt id='1005'> +1.1253000e+04 </wgt> </rwgt> </event> </LesHouchesEvents> """ open(pjoin(self.path, 'event.lhe'), 'w').write(input) input_lhe = lhe_parser.EventFile(pjoin(self.path, 'event.lhe.gz')) output_lhe = lhe_parser.EventFile(pjoin(self.path, 'event2.lhe.gz'), 'w') output_lhe.write(input_lhe.banner) for event in input_lhe: output_lhe.write(str(event)) output_lhe.close() self.assertTrue(pjoin(self.path, 'event2.lhe.gz')) text = open(pjoin(self.path, 'event2.lhe.gz')).read() self.assertFalse(text.startswith('<LesHouchesEvents version="1.0">')) misc.gunzip(pjoin(self.path, 'event2.lhe.gz')) self.assertTrue(pjoin(self.path, 'event2.lhe')) input_lhe = lhe_parser.EventFile(pjoin(self.path, 'event.lhe'))
def test_read_write_lhe(self): """test that we can read/write an lhe event file""" input = """<LesHouchesEvents version="1.0"> <header> DATA </header> <init> 2212 2212 0.70000000000E+04 0.70000000000E+04 0 0 10042 10042 3 1 0.16531958660E+02 0.18860728290E+00 0.17208000000E+00 0 </init> <event> 4 0 +1.7208000e-01 1.00890300e+02 7.95774700e-02 1.27947900e-01 -1 -1 0 0 0 501 +0.0000000e+00 +0.0000000e+00 +1.1943355e+01 1.19433546e+01 0.00000000e+00 0.0000e+00 1.0000e+00 2 -1 0 0 501 0 +0.0000000e+00 +0.0000000e+00 -1.0679326e+03 1.06793262e+03 0.00000000e+00 0.0000e+00 -1.0000e+00 24 1 1 2 0 0 +6.0417155e+00 +4.2744556e+01 -7.9238049e+02 7.97619997e+02 8.04190073e+01 3.4933e-25 -1.0000e+00 23 1 1 2 0 0 -6.0417155e+00 -4.2744556e+01 -2.6360878e+02 2.82255979e+02 9.11880035e+01 1.8975e-26 1.0000e+00 </event> <event> 4 0 +1.7208000e-01 1.00890300e+02 7.95774700e-02 1.27947900e-01 -1 -1 0 0 0 501 +0.0000000e+00 +0.0000000e+00 +1.1943355e+01 1.19433546e+01 0.00000000e+00 0.0000e+00 1.0000e+00 2 -1 0 0 501 0 +0.0000000e+00 +0.0000000e+00 -1.0679326e+03 1.06793262e+03 0.00000000e+00 0.0000e+00 -1.0000e+00 24 1 1 2 0 0 +6.0417155e+00 +4.2744556e+01 -7.9238049e+02 7.97619997e+02 8.04190073e+01 3.4933e-25 -1.0000e+00 23 1 1 2 0 0 -6.0417155e+00 -4.2744556e+01 -2.6360878e+02 2.82255979e+02 9.11880035e+01 1.8975e-26 1.0000e+00 # balbalblb #bbbb3 </event> <event> 7 66 +1.5024446e-03 3.15138740e+02 7.95774720e-02 9.66701260e-02 21 -1 0 0 502 501 +0.0000000e+00 +0.0000000e+00 -6.4150959e+01 6.41553430e+01 7.49996552e-01 0.0000e+00 0.0000e+00 2 -1 0 0 501 0 +0.0000000e+00 +0.0000000e+00 +8.1067989e+02 8.10679950e+02 3.11899968e-01 0.0000e+00 0.0000e+00 24 2 1 2 0 0 -1.5294533e+02 +1.0783429e+01 +4.5796553e+02 4.89600040e+02 8.04190039e+01 0.0000e+00 0.0000e+00 2 1 3 3 503 0 -1.5351296e+02 +1.2743130e+01 +4.6093709e+02 4.85995489e+02 0.00000000e+00 0.0000e+00 0.0000e+00 -1 1 3 3 0 503 +5.6763429e-01 -1.9597014e+00 -2.9715566e+00 3.60455091e+00 0.00000000e+00 0.0000e+00 0.0000e+00 23 1 1 2 0 0 +4.4740095e+01 +3.2658177e+01 +4.6168760e+01 1.16254200e+02 9.11880036e+01 0.0000e+00 0.0000e+00 1 1 1 2 502 0 +1.0820523e+02 -4.3441605e+01 +2.4239464e+02 2.68981060e+02 3.22945297e-01 0.0000e+00 0.0000e+00 # 2 5 2 2 1 0.11659994e+03 0.11659994e+03 8 0 0 0.10000000e+01 0.88172677e+00 0.11416728e+01 0.00000000e+00 0.00000000e+00 <rwgt> <wgt id='1001'> +9.1696000e+03 </wgt> <wgt id='1002'> +1.1264000e+04 </wgt> <wgt id='1003'> +6.9795000e+03 </wgt> <wgt id='1004'> +9.1513000e+03 </wgt> <wgt id='1005'> +1.1253000e+04 </wgt> </rwgt> </event> </LesHouchesEvents> """ open(pjoin(self.path, 'event.lhe'), 'w').write(input) input = lhe_parser.EventFile(pjoin(self.path, 'event.lhe')) self.assertEqual( input.banner, """<LesHouchesEvents version="1.0"> <header> DATA </header> <init> 2212 2212 0.70000000000E+04 0.70000000000E+04 0 0 10042 10042 3 1 0.16531958660E+02 0.18860728290E+00 0.17208000000E+00 0 </init> """) nb_event = 0 txt = "" for event in input: nb_event += 1 new = lhe_parser.Event(text=str(event)) for part1, part2 in zip(event, new): self.assertEqual(part1, part2) self.assertEqual(new, event, '%s \n !=\n %s' % (new, event)) txt += str(event) self.assertEqual(nb_event, 3) target = """<event> 4 0 +1.7208000e-01 1.00890300e+02 7.95774700e-02 1.27947900e-01 -1 -1 0 0 0 501 +0.0000000000e+00 +0.0000000000e+00 +1.1943355000e+01 1.1943354600e+01 0.0000000000e+00 0.0000e+00 1.0000e+00 2 -1 0 0 501 0 +0.0000000000e+00 +0.0000000000e+00 -1.0679326000e+03 1.0679326200e+03 0.0000000000e+00 0.0000e+00 -1.0000e+00 24 1 1 2 0 0 +6.0417155000e+00 +4.2744556000e+01 -7.9238049000e+02 7.9761999700e+02 8.0419007300e+01 3.4933e-25 -1.0000e+00 23 1 1 2 0 0 -6.0417155000e+00 -4.2744556000e+01 -2.6360878000e+02 2.8225597900e+02 9.1188003500e+01 1.8975e-26 1.0000e+00 </event> <event> 4 0 +1.7208000e-01 1.00890300e+02 7.95774700e-02 1.27947900e-01 -1 -1 0 0 0 501 +0.0000000000e+00 +0.0000000000e+00 +1.1943355000e+01 1.1943354600e+01 0.0000000000e+00 0.0000e+00 1.0000e+00 2 -1 0 0 501 0 +0.0000000000e+00 +0.0000000000e+00 -1.0679326000e+03 1.0679326200e+03 0.0000000000e+00 0.0000e+00 -1.0000e+00 24 1 1 2 0 0 +6.0417155000e+00 +4.2744556000e+01 -7.9238049000e+02 7.9761999700e+02 8.0419007300e+01 3.4933e-25 -1.0000e+00 23 1 1 2 0 0 -6.0417155000e+00 -4.2744556000e+01 -2.6360878000e+02 2.8225597900e+02 9.1188003500e+01 1.8975e-26 1.0000e+00 # balbalblb #bbbb3 </event> <event> 7 66 +1.5024446e-03 3.15138740e+02 7.95774720e-02 9.66701260e-02 21 -1 0 0 502 501 +0.0000000000e+00 +0.0000000000e+00 -6.4150959000e+01 6.4155343000e+01 7.4999655200e-01 0.0000e+00 0.0000e+00 2 -1 0 0 501 0 +0.0000000000e+00 +0.0000000000e+00 +8.1067989000e+02 8.1067995000e+02 3.1189996800e-01 0.0000e+00 0.0000e+00 24 2 1 2 0 0 -1.5294533000e+02 +1.0783429000e+01 +4.5796553000e+02 4.8960004000e+02 8.0419003900e+01 0.0000e+00 0.0000e+00 2 1 3 3 503 0 -1.5351296000e+02 +1.2743130000e+01 +4.6093709000e+02 4.8599548900e+02 0.0000000000e+00 0.0000e+00 0.0000e+00 -1 1 3 3 0 503 +5.6763429000e-01 -1.9597014000e+00 -2.9715566000e+00 3.6045509100e+00 0.0000000000e+00 0.0000e+00 0.0000e+00 23 1 1 2 0 0 +4.4740095000e+01 +3.2658177000e+01 +4.6168760000e+01 1.1625420000e+02 9.1188003600e+01 0.0000e+00 0.0000e+00 1 1 1 2 502 0 +1.0820523000e+02 -4.3441605000e+01 +2.4239464000e+02 2.6898106000e+02 3.2294529700e-01 0.0000e+00 0.0000e+00 # 2 5 2 2 1 0.11659994e+03 0.11659994e+03 8 0 0 0.10000000e+01 0.88172677e+00 0.11416728e+01 0.00000000e+00 0.00000000e+00 <rwgt> <wgt id='1001'> +9.1696000e+03 </wgt> <wgt id='1002'> +1.1264000e+04 </wgt> <wgt id='1003'> +6.9795000e+03 </wgt> <wgt id='1004'> +9.1513000e+03 </wgt> <wgt id='1005'> +1.1253000e+04 </wgt> </rwgt> </event> """ self.assertEqual(target.split('\n'), txt.split('\n'))
def generate_events(pdg, nb_event, mg5, restrict_file=None, cumul=False): """generate new events for this particle restrict_file allow to only generate a subset of the definition cumul allow to merge all the definition in one run (add process) to generate events according to cross-section """ part = self.model.get_particle(pdg) name = part.get_name() out = {} logger.info("generate %s decay event for particle %s" % (nb_event, name)) if name not in self.list_branches: return out for i, proc in enumerate(self.list_branches[name]): if restrict_file and i not in restrict_file: continue decay_dir = pjoin( self.path_me, "decay_%s_%s" % (str(pdg).replace("-", "x"), i)) if not os.path.exists(decay_dir): if cumul: mg5.exec_cmd("generate %s" % proc) for j, proc2 in enumerate( self.list_branches[name][1:]): if restrict_file and j not in restrict_file: raise Exception # Do not see how this can happen mg5.exec_cmd("add process %s" % proc2) mg5.exec_cmd("output %s -f" % decay_dir) else: mg5.exec_cmd("generate %s" % proc) mg5.exec_cmd("output %s -f" % decay_dir) options = dict(mg5.options) import madgraph.interface.madevent_interface as madevent_interface me5_cmd = madevent_interface.MadEventCmdShell(me_dir=os.path.realpath(\ decay_dir), options=options) me5_cmd.options["automatic_html_opening"] = False if self.options["run_card"]: run_card = self.options["run_card"] else: run_card = banner.RunCard( pjoin(decay_dir, "Cards", "run_card.dat")) run_card["nevents"] = int(1.2 * nb_event) run_card["iseed"] = self.seed run_card.write(pjoin(decay_dir, "Cards", "run_card.dat")) param_card = self.banner['slha'] open(pjoin(decay_dir, "Cards", "param_card.dat"), "w").write(param_card) self.seed += 1 me5_cmd.exec_cmd("generate_events run_01 -f") me5_cmd.exec_cmd("exit") out[i] = lhe_parser.EventFile( pjoin(decay_dir, "Events", 'run_01', 'unweighted_events.lhe.gz')) if cumul: break return out