def save(self, folder, save_model=False): """ Saves the estimator ensemble to a folder. Parameters ---------- folder : str Path to the folder. save_model : bool, optional If True, the whole model is saved in addition to the state dict. This is not necessary for loading it again with Ensemble.load(), but can be useful for debugging, for instance to plot the computational graph. Returns ------- None """ # Check paths create_missing_folders([folder]) # Save ensemble settings logger.debug("Saving ensemble setup to %s/ensemble.json", folder) settings = {"estimator_type": self.estimator_type, "n_estimators": self.n_estimators} with open(f"{folder}/ensemble.json", "w") as f: json.dump(settings, f) # Save estimators for i, estimator in enumerate(self.estimators): estimator.save(f"{folder}/estimator_{i}", save_model=save_model)
def run_mg_reweighting(mg_process_directory, run_name, reweight_card_file=None, initial_command=None, log_file=None): """ Runs MG reweighting. Parameters ---------- mg_process_directory : str Path to the MG process directory. run_name : str Run name. reweight_card_file : str or None, optional Path to the MadGraph reweight card. If None, the card present in the process folder is used. (Default value = None) initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). Default value: None. log_file : str or None, optional Path to a log file in which the MadGraph output is saved. Default value: None. Returns ------- bash_script_call : str How to call this script. """ # Preparations create_missing_folders([os.path.dirname(log_file)]) # Prepare run... logger.info("Starting reweighting of an existing sample in %s", mg_process_directory) # Copy cards if reweight_card_file is not None: shutil.copyfile(reweight_card_file, mg_process_directory + "/Cards/reweight_card.dat") # Call MG5 reweight feature if initial_command is None: initial_command = "" else: initial_command = initial_command + "; " _ = call_command("{}{}/bin/madevent reweight {} -f".format( initial_command, mg_process_directory, run_name), log_file=log_file)
def save(self, filename): """ Saves MadMiner setup into a file. The file format follows the HDF5 standard. The saved information includes: * the parameter definitions, * the benchmark points, * the systematics setup (if defined), and * the morphing setup (if defined). This file is an important input to later stages in the analysis chain, including the processing of generated events, extraction of training samples, and calculation of Fisher information matrices. In these downstream tasks, additional information will be written to the MadMiner file, including the observations and event weights. Parameters ---------- filename : str Path to the MadMiner file. Returns ------- None """ create_missing_folders([os.path.dirname(filename)]) if self.morpher is not None: logger.info("Saving setup (including morphing) to %s", filename) save_madminer_settings( filename=filename, parameters=self.parameters, benchmarks=self.benchmarks, morphing_components=self.morpher.components, morphing_matrix=self.morpher.morphing_matrix, systematics=self.systematics, finite_difference_benchmarks=self.finite_difference_benchmarks, finite_difference_epsilon=self.finite_difference_epsilon, overwrite_existing_files=True, ) else: logger.info("Saving setup (without morphing) to %s", filename) save_madminer_settings( filename=filename, parameters=self.parameters, benchmarks=self.benchmarks, systematics=self.systematics, finite_difference_benchmarks=self.finite_difference_benchmarks, finite_difference_epsilon=self.finite_difference_epsilon, overwrite_existing_files=True, )
def run_multiple( self, mg_directory, proc_card_file, param_card_template_file, run_card_files, mg_process_directory=None, pythia8_card_file=None, sample_benchmarks=None, is_background=False, only_prepare_script=False, ufo_model_directory=None, log_directory=None, temp_directory=None, initial_command=None, python2_override=False, ): """ High-level function that creates the the MadGraph process, all required cards, and prepares or runs the event generation for multiple combinations of run_cards or importance samplings (`sample_benchmarks`). If `only_prepare_scripts=True`, the event generation is not run directly, but a bash script is created in `<process_folder>/madminer/run.sh` that will start the event generation with the correct settings. Parameters ---------- mg_directory : str Path to the MadGraph 5 base directory. proc_card_file : str Path to the process card that tells MadGraph how to generate the process. param_card_template_file : str Path to a param card that will be used as template to create the appropriate param cards for these runs. run_card_files : list of str Paths to the MadGraph run card. mg_process_directory : str or None, optional Path to the MG process directory. If None, MadMiner uses ./MG_process. Default value: None. pythia8_card_file : str, optional Path to the MadGraph Pythia8 card. If None, the card present in the process folder is used. Default value: None. sample_benchmarks : list of str or None, optional Lists the names of benchmarks that should be used to sample events. A different sampling does not change the expected differential cross sections, but will change which regions of phase space have many events (small variance) or few events (high variance). If None, a run is started for each of the benchmarks, which should map out all regions of phase space well. Default value: None. is_background : bool, optional Should be True for background processes, i.e. process in which the differential cross section does not depend on the parameters (i.e. is the same for all benchmarks). In this case, no reweighting is run, which can substantially speed up the event generation. Default value: False. only_prepare_script : bool, optional If True, the event generation is not started, but instead a run.sh script is created in the process directory. Default value: False. only_prepare_script : bool, optional If True, MadGraph is not executed, but instead a run.sh script is created in the process directory. Default value: False. ufo_model_directory : str or None, optional Path to an UFO model directory that should be used, but is not yet installed in mg_directory/models. The model will be copied to the MadGraph model directory before the process directory is generated. (Default value = None) log_directory : str or None, optional Directory for log files with the MadGraph output. If None, ./logs is used. Default value: None. temp_directory : str or None, optional Path to a temporary directory. If None, a system default is used. Default value: None. initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). Default value: None. python2_override : bool, optional If True, MadMiner explicitly calls "python2" instead of relying on the system Python version to be Python 2.6 or Python 2.7. If you use systematics, make sure that the python interface of LHAPDF was compiled with the Python version you are using. Default: False. Returns ------- None """ # Defaults if mg_process_directory is None: mg_process_directory = "./MG_process" if temp_directory is None: temp_directory = tempfile.gettempdir() if log_directory is None: log_directory = "./logs" if sample_benchmarks is None: sample_benchmarks = [benchmark for benchmark in self.benchmarks] # Generate process folder log_file_generate = log_directory + "/generate.log" generate_mg_process( mg_directory, temp_directory, proc_card_file, mg_process_directory, ufo_model_directory=ufo_model_directory, initial_command=initial_command, log_file=log_file_generate, explicit_python_call=python2_override, ) # Make MadMiner folders create_missing_folders([ mg_process_directory + "/madminer", mg_process_directory + "/madminer/cards", mg_process_directory + "/madminer/scripts", ]) # Loop over settings i = 0 mg_scripts = [] for run_card_file in run_card_files: for sample_benchmark in sample_benchmarks: # Files script_file = "madminer/scripts/run_{}.sh".format(i) log_file_run = "run_{}.log".format(i) mg_commands_filename = "/madminer/cards/mg_commands_{}.dat".format( i) param_card_file = "/madminer/cards/param_card_{}.dat".format(i) reweight_card_file = "/madminer/cards/reweight_card_{}.dat".format( i) new_pythia8_card_file = None if pythia8_card_file is not None: new_pythia8_card_file = "/madminer/cards/pythia8_card_{}.dat".format( i) new_run_card_file = None if run_card_file is not None: new_run_card_file = "/madminer/cards/run_card_{}.dat".format( i) logger.info("Run %s", i) logger.info(" Sampling from benchmark: %s", sample_benchmark) logger.info(" Original run card: %s", run_card_file) logger.info(" Original Pythia8 card: %s", pythia8_card_file) logger.info(" Copied run card: %s", new_run_card_file) logger.info(" Copied Pythia8 card: %s", new_pythia8_card_file) logger.info(" Param card: %s", param_card_file) logger.info(" Reweight card: %s", reweight_card_file) logger.info(" Log file: %s", log_file_run) # Check input if run_card_file is None and self.systematics is not None: logger.warning( "Warning: No run card given, but systematics set up. The correct systematics" " settings are not set automatically. Make sure to set them correctly!" ) # Create param and reweight cards self._export_cards( param_card_template_file, mg_process_directory, sample_benchmark=sample_benchmark, param_card_filename=mg_process_directory + "/" + param_card_file, reweight_card_filename=mg_process_directory + "/" + reweight_card_file, ) # Create run card if run_card_file is not None: export_run_card( template_filename=run_card_file, run_card_filename=mg_process_directory + "/" + new_run_card_file, systematics=self.systematics, ) # Copy Pythia card if pythia8_card_file is not None: copy_file( pythia8_card_file, mg_process_directory + "/" + new_pythia8_card_file) # Run MG and Pythia if only_prepare_script: mg_script = setup_mg_with_scripts( mg_process_directory, proc_card_filename_from_mgprocdir=mg_commands_filename, run_card_file_from_mgprocdir=new_run_card_file, param_card_file_from_mgprocdir=param_card_file, reweight_card_file_from_mgprocdir=reweight_card_file, pythia8_card_file_from_mgprocdir=None if new_pythia8_card_file is None else new_pythia8_card_file, is_background=is_background, script_file_from_mgprocdir=script_file, initial_command=initial_command, log_dir=log_directory, log_file_from_logdir=log_file_run, explicit_python_call=python2_override, ) mg_scripts.append(mg_script) else: run_mg( mg_directory, mg_process_directory, mg_process_directory + "/" + mg_commands_filename, mg_process_directory + "/" + new_run_card_file, mg_process_directory + "/" + param_card_file, mg_process_directory + "/" + reweight_card_file, None if new_pythia8_card_file is None else mg_process_directory + "/" + new_pythia8_card_file, is_background=is_background, initial_command=initial_command, log_file=log_directory + "/" + log_file_run, explicit_python_call=python2_override, ) i += 1 n_runs_total = i # Master shell script if only_prepare_script: master_script_filename = "{}/madminer/run.sh".format( mg_process_directory) create_master_script(log_directory, master_script_filename, mg_directory, mg_process_directory, mg_scripts) logger.info( "To generate events, please run:\n\n %s [MG_directory] [MG_process_directory] [log_dir]\n\n", master_script_filename, ) else: expected_event_files = [ mg_process_directory + "/Events/run_{:02d}".format(i + 1) for i in range(n_runs_total) ] expected_event_files = "\n".join(expected_event_files) logger.info( "Finished running MadGraph! Please check that events were succesfully generated in the following " "folders:\n\n%s\n\n", expected_event_files, )
def setup_mg_reweighting_with_scripts( mg_process_directory, run_name, reweight_card_file_from_mgprocdir=None, script_file_from_mgprocdir=None, initial_command=None, log_dir=None, log_file_from_logdir=None, ): """ Prepares a bash script that will start the event generation. Parameters ---------- mg_process_directory : str Path to the MG process directory. reweight_card_file_from_mgprocdir : str or None, optional Path to the MadGraph reweight card, relative from mg_process_directory. If None, the card present in the process folder is used. Default value: None. script_file_from_mgprocdir : str or None, optional This sets where the shell script to run the reweighting is generated, relative from mg_process_directory. If None, a default filename in `mg_process_directory/madminer` is used. Default value: None. initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). Default value: None. log_dir : str or None, optional Log directory. Default value: None. log_file_from_logdir : str or None, optional Path to a log file in which the MadGraph output is saved, relative from the default log directory. Default value: None. Returns ------- bash_script_call : str How to call this script. """ # Preparations if log_dir is not None: create_missing_folders([log_dir]) # Prepare run... logger.info("Preparing script to reweight an existing sample in %s", mg_process_directory) # Bash script can optionally provide MG path or process directory mg_process_directory_placeholder = "$mgprocdir" log_dir_placeholder = "$mmlogdir" placeholder_definition = r"mgprocdir=${1:-" + mg_process_directory + r"}" + "\n" placeholder_definition += r"mmlogdir=${2:-" + log_dir + r"}" if script_file_from_mgprocdir is None: script_file = mg_process_directory + "/madminer/scripts/madminer_reweight_{}.sh".format( run_name) else: script_file = mg_process_directory + "/" + script_file_from_mgprocdir script_filename = os.path.basename(script_file) if log_file_from_logdir is None: log_file_from_logdir = "/log.log" # Initial commands if initial_command is None: initial_command = "" # Card copying commands if reweight_card_file_from_mgprocdir is not None: copy_commands = "cp {}/{} {}{}\n".format( mg_process_directory_placeholder, reweight_card_file_from_mgprocdir, mg_process_directory_placeholder, "/Cards/reweight_card.dat", ) else: copy_commands = "" # Put together script script = ( "#!/bin/bash\n\n# Script generated by MadMiner\n\n# Usage: {} MG_process_directory log_dir\n\n" + "{}\n\n{}\n\n{}\n\n{}/bin/madevent reweight {} -f > {}/{}\n").format( script_filename, initial_command, placeholder_definition, copy_commands, mg_process_directory_placeholder, run_name, log_dir_placeholder, log_file_from_logdir, ) with open(script_file, "w") as file: file.write(script) make_file_executable(script_file) # How to call it from master script call_instruction = "{}/{} [MG_process_directory] [log_directory]".format( mg_process_directory, script_file_from_mgprocdir) return call_instruction
def run_mg( mg_directory, mg_process_directory, proc_card_filename=None, run_card_file=None, param_card_file=None, reweight_card_file=None, pythia8_card_file=None, configuration_card_file=None, is_background=False, initial_command=None, log_file=None, explicit_python_call=False, order="LO", python_executable=None, ): """ Calls MadGraph to generate events. Parameters ---------- mg_directory : str Path to the MadGraph 5 base directory. mg_process_directory : str Path to the MG process directory. proc_card_filename : str or None, optional Filename for the MG command card that will be generated. If None, a default filename in the MG process directory will be chosen. run_card_file : str or None, optional Path to the MadGraph run card. If None, the card present in the process folder is used. Default value: None) param_card_file : str or None, optional Path to the MadGraph param card. If None, the card present in the process folder is used. Default value: None) reweight_card_file : str or None, optional Path to the MadGraph reweight card. If None, the card present in the process folder is used. (Default value = None) pythia8_card_file : str or None, optional Path to the MadGraph Pythia8 card. If None, Pythia is not run. Default value: None. configuration_card_file : str or None, optional Path to the MadGraph configuration card. If None, the card present in the process folder is used. (Default value: None). is_background : bool, optional Should be True for background processes, i.e. process in which the differential cross section does not depend on the parameters (and would be the same for all benchmarks). In this case, no reweighting is run, which can substantially speed up the event generation. Default value: False. initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). Default value: None. log_file : str or None, optional Path to a log file in which the MadGraph output is saved. Default value: None. explicit_python_call : bool, optional Calls `python2.7` instead of `python`. Returns ------- None """ # Preparations create_missing_folders([mg_process_directory, os.path.dirname(log_file)]) if proc_card_filename is not None: create_missing_folders([os.path.dirname(proc_card_filename)]) # Just run it already logger.info("Starting MadGraph and Pythia in %s", mg_process_directory) # Copy cards if run_card_file is not None: shutil.copyfile(run_card_file, mg_process_directory + "/Cards/run_card.dat") if param_card_file is not None: shutil.copyfile(param_card_file, mg_process_directory + "/Cards/param_card.dat") if reweight_card_file is not None and not is_background: shutil.copyfile(reweight_card_file, mg_process_directory + "/Cards/reweight_card.dat") if pythia8_card_file is not None and order == "LO": shutil.copyfile(pythia8_card_file, mg_process_directory + "/Cards/pythia8_card.dat") if pythia8_card_file is not None and order == "NLO": shutil.copyfile(pythia8_card_file, mg_process_directory + "/Cards/shower_card.dat") if configuration_card_file is not None: shutil.copyfile(configuration_card_file, mg_process_directory + "/Cards/me5_configuration.txt") # Find filenames for process card and script if proc_card_filename is None: for i in range(1000): proc_card_filename = mg_process_directory + "/Cards/start_event_generation_{}.mg5".format( i) if not os.path.isfile(proc_card_filename): break # MG commands shower_option = "OFF" if pythia8_card_file is None else "Pythia8" reweight_option = "OFF" if is_background else "ON" mg_commands = """ launch {} shower={} detector=OFF analysis=OFF madspin=OFF reweight={} done """.format(mg_process_directory, shower_option, reweight_option) with open(proc_card_filename, "w") as file: file.write(mg_commands) # Call MG5 if initial_command is None: initial_command = "" else: initial_command = initial_command + "; " # Explicitly call Python 2 if necessary if explicit_python_call: python_call = python_executable + " " if python_executable is not None else "python2.7 " else: python_call = "" _ = call_command(initial_command + python_call + mg_directory + "/bin/mg5_aMC " + proc_card_filename, log_file=log_file)
def generate_mg_process( mg_directory, temp_directory, proc_card_file, mg_process_directory, ufo_model_directory=None, log_file=None, initial_command=None, explicit_python_call=False, python_executable=None, ): """ Calls MadGraph to create the process folder. Parameters ---------- mg_directory : str Path to the MadGraph 5 directory. temp_directory : str Path to a directory for temporary files. proc_card_file : str Path to the process card that tells MadGraph how to generate the process. mg_process_directory : str Path to the MG process directory. ufo_model_directory : str or None, optional Path to a UFO model that is not yet installed. It will be copied to the MG directory before the process card is executed. Default value: None. initial_command : str or None, optional Initial bash commands that have to be executed before MG is run (e.g. to load the correct virtual environment). Default value: None. log_file : str or None, optional Path to a log file in which the MadGraph output is saved. Default value: None. explicit_python_call : bool, optional Calls `python2.7` instead of `python`. python_executable : None or str, optional Overwrites the default Python executable Returns ------- None """ # Preparations logger.info("Generating MadGraph process folder from %s at %s", proc_card_file, mg_process_directory) create_missing_folders( [temp_directory, mg_process_directory, os.path.dirname(log_file)]) if ufo_model_directory is not None: copy_ufo_model(ufo_model_directory, mg_directory) # MG commands temp_proc_card_file = temp_directory + "/generate.mg5" shutil.copyfile(proc_card_file, temp_proc_card_file) with open(temp_proc_card_file, "a") as myfile: myfile.write("\n\noutput " + mg_process_directory) # Call MG5 if initial_command is None: initial_command = "" else: initial_command = initial_command + "; " # Explicitly call Python 2 if necessary if explicit_python_call: python_call = python_executable + " " if python_executable is not None else "python2.7 " else: python_call = "" logger.info( "Calling MadGraph: %s", initial_command + python_call + mg_directory + "/bin/mg5_aMC " + temp_proc_card_file) _ = call_command(initial_command + python_call + mg_directory + "/bin/mg5_aMC " + temp_proc_card_file, log_file=log_file)
def setup_mg_with_scripts( mg_process_directory, proc_card_filename_from_mgprocdir=None, run_card_file_from_mgprocdir=None, param_card_file_from_mgprocdir=None, reweight_card_file_from_mgprocdir=None, pythia8_card_file_from_mgprocdir=None, configuration_file_from_mgprocdir=None, is_background=False, script_file_from_mgprocdir=None, initial_command=None, log_dir=None, log_file_from_logdir=None, explicit_python_call=False, order="LO", python_executable=None, ): """ Prepares a bash script that will start the event generation. Parameters ---------- mg_process_directory : str Path to the MG process directory. proc_card_filename_from_mgprocdir : str or None, optional Filename for the MG command card that will be generated, relative from mg_process_directory. If None, a default filename in the MG process directory will be chosen. run_card_file_from_mgprocdir : str or None, optional Path to the MadGraph run card, relative from mg_process_directory. If None, the card present in the process folder is used. Default value: None. param_card_file_from_mgprocdir : str or None, optional Path to the MadGraph run card, relative from mg_process_directory. If None, the card present in the process folder is used. Default value: None. reweight_card_file_from_mgprocdir : str or None, optional Path to the MadGraph reweight card, relative from mg_process_directory. If None, the card present in the process folder is used. Default value: None. pythia8_card_file_from_mgprocdir : str or None, optional Path to the MadGraph Pythia8 card, relative from mg_process_directory. If None, Pythia is not run. Default value: None. configuration_file_from_mgprocdir : str or None, optional Path to the MadGraph me5_configuration card, relative from mg_process_directory. If None, the card present in the process folder is used. Default value: None. is_background : bool, optional Should be True for background processes, i.e. process in which the differential cross section does not depend on the parameters (and would be the same for all benchmarks). In this case, no reweighting is run, which can substantially speed up the event generation. Default value: False. script_file_from_mgprocdir : str or None, optional This sets where the shell script to run MG and Pythia is generated, relative from mg_process_directory. If None, a default filename in `mg_process_directory/madminer` is used. Default value: None. initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). Default value: None. log_dir : str or None, optional Log directory. Default value: None. log_file_from_logdir : str or None, optional Path to a log file in which the MadGraph output is saved, relative from the default log directory. Default value: None. explicit_python_call : bool, optional Calls `python2.7` instead of `python`. python_executable : None or str, optional Overwrites the default Python executable Returns ------- bash_script_call : str How to call this script. """ # Preparations create_missing_folders([mg_process_directory]) if log_dir is not None: create_missing_folders([log_dir]) if proc_card_filename_from_mgprocdir is not None: create_missing_folders([ os.path.dirname(mg_process_directory + "/" + proc_card_filename_from_mgprocdir) ]) # Prepare run... logger.info("Preparing script to run MadGraph and Pythia in %s", mg_process_directory) # Bash script can optionally provide MG path or process directory mg_directory_placeholder = "$mgdir" mg_process_directory_placeholder = "$mgprocdir" log_dir_placeholder = "$mmlogdir" placeholder_definition = "mgdir=$1\nmgprocdir=$2\nmmlogdir=$3" # Find filenames for process card and script if proc_card_filename_from_mgprocdir is None: for i in range(1000): proc_card_filename_from_mgprocdir = "/Cards/start_event_generation_{}.mg5".format( i) if not os.path.isfile(mg_process_directory + "/" + proc_card_filename_from_mgprocdir): break else: proc_card_filename = mg_process_directory + "/" + proc_card_filename_from_mgprocdir if script_file_from_mgprocdir is None: for i in range(1000): script_file = mg_process_directory + "/madminer/scripts/madminer_run_{}.sh".format( i) if not os.path.isfile(script_file): break else: script_file = mg_process_directory + "/" + script_file_from_mgprocdir script_filename = os.path.basename(script_file) if log_file_from_logdir is None: log_file_from_logdir = "/log.log" # MG commands shower_option = "OFF" if pythia8_card_file_from_mgprocdir is None else "Pythia8" reweight_option = "OFF" if is_background else "ON" mg_commands = """ launch {} shower={} detector=OFF analysis=OFF madspin=OFF reweight={} done """.format(mg_process_directory_placeholder, shower_option, reweight_option) with open(proc_card_filename, "w") as file: file.write(mg_commands) # Initial commands if initial_command is None: initial_command = "" # Card copying commands copy_commands = "" if run_card_file_from_mgprocdir is not None: copy_commands += "cp {}/{} {}{}\n".format( mg_process_directory_placeholder, run_card_file_from_mgprocdir, mg_process_directory_placeholder, "/Cards/run_card.dat", ) if param_card_file_from_mgprocdir is not None: copy_commands += "cp {}/{} {}{}\n".format( mg_process_directory_placeholder, param_card_file_from_mgprocdir, mg_process_directory_placeholder, "/Cards/param_card.dat", ) if reweight_card_file_from_mgprocdir is not None and not is_background: copy_commands += "cp {}/{} {}{}\n".format( mg_process_directory_placeholder, reweight_card_file_from_mgprocdir, mg_process_directory_placeholder, "/Cards/reweight_card.dat", ) if pythia8_card_file_from_mgprocdir is not None and order == "LO": copy_commands += "cp {}/{} {}{}\n".format( mg_process_directory_placeholder, pythia8_card_file_from_mgprocdir, mg_process_directory_placeholder, "/Cards/pythia8_card.dat", ) elif pythia8_card_file_from_mgprocdir is not None and order == "NLO": copy_commands += "cp {}/{} {}{}\n".format( mg_process_directory_placeholder, pythia8_card_file_from_mgprocdir, mg_process_directory_placeholder, "/Cards/shower_card.dat", ) if configuration_file_from_mgprocdir is not None: copy_commands += "cp {}/{} {}{}\n".format( mg_process_directory_placeholder, configuration_file_from_mgprocdir, mg_process_directory_placeholder, "/Cards/me5_configuration.txt", ) # Replace environment variable in proc card replacement_command = """sed -e 's@\$mgprocdir@'"$mgprocdir"'@' {}/{} > {}/{}""".format( mg_process_directory_placeholder, proc_card_filename_from_mgprocdir, mg_process_directory_placeholder, "Cards/mg_commands.mg5", ) # Explicitly call Python 2 if necessary if explicit_python_call: python_call = python_executable + " " if python_executable is not None else "python2.7 " else: python_call = "" # Put together script script = ( "#!/bin/bash\n\n# Script generated by MadMiner\n\n# Usage: {} MG_directory MG_process_directory log_dir\n\n" + "{}\n\n{}\n\n{}\n{}\n\n{} {}/bin/mg5_aMC {}/{} > {}/{}\n").format( script_filename, initial_command, placeholder_definition, copy_commands, replacement_command, python_call, mg_directory_placeholder, mg_process_directory_placeholder, "Cards/mg_commands.mg5", log_dir_placeholder, log_file_from_logdir, ) with open(script_file, "w") as file: file.write(script) make_file_executable(script_file) # How to call it from master script call_placeholder = "{}/{} {} {} {}".format( mg_process_directory_placeholder, script_file_from_mgprocdir, mg_directory_placeholder, mg_process_directory_placeholder, log_dir_placeholder, ) return call_placeholder
def run_multiple( self, mg_directory, proc_card_file, param_card_template_file, run_card_files, mg_process_directory=None, pythia8_card_file=None, sample_benchmarks=None, is_background=False, only_prepare_script=False, ufo_model_directory=None, log_directory=None, temp_directory=None, initial_command=None, ): """ High-level function that creates the the MadGraph process, all required cards, and prepares or runs the event generation for multiple combinations of run_cards or importance samplings (`sample_benchmarks`). If `only_prepare_scripts=True`, the event generation is not run directly, but a bash script is created in `<process_folder>/madminer/run.sh` that will start the event generation with the correct settings. Parameters ---------- mg_directory : str Path to the MadGraph 5 base directory. proc_card_file : str Path to the process card that tells MadGraph how to generate the process. param_card_template_file : str Path to a param card that will be used as template to create the appropriate param cards for these runs. run_card_files : list of str Paths to the MadGraph run card. mg_process_directory : str or None, optional Path to the MG process directory. If None, MadMiner uses ./MG_process. Default value: None. pythia8_card_file : str, optional Path to the MadGraph Pythia8 card. If None, the card present in the process folder is used. Default value: None. sample_benchmarks : list of str or None, optional Lists the names of benchmarks that should be used to sample events. A different sampling does not change the expected differential cross sections, but will change which regions of phase space have many events (small variance) or few events (high variance). If None, a run is started for each of the benchmarks, which should map out all regions of phase space well. Default value: None. is_background : bool, optional Should be True for background processes, i.e. process in which the differential cross section does not depend on the parameters (i.e. is the same for all benchmarks). In this case, no reweighting is run, which can substantially speed up the event generation. Default value: False. only_prepare_script : bool, optional If True, the event generation is not started, but instead a run.sh script is created in the process directory. Default value: False. only_prepare_script : bool, optional If True, MadGraph is not executed, but instead a run.sh script is created in the process directory. Default value: False. ufo_model_directory : str or None, optional Path to an UFO model directory that should be used, but is not yet installed in mg_directory/models. The model will be copied to the MadGraph model directory before the process directory is generated. (Default value = None) log_directory : str or None, optional Directory for log files with the MadGraph output. If None, ./logs is used. Default value: None. temp_directory : str or None, optional Path to a temporary directory. If None, a system default is used. Default value: None. initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). Default value: None. Returns ------- None """ # Defaults if mg_process_directory is None: mg_process_directory = "./MG_process" if temp_directory is None: temp_directory = tempfile.gettempdir() if log_directory is None: log_directory = "./logs" if sample_benchmarks is None: sample_benchmarks = [benchmark for benchmark in self.benchmarks] # Generate process folder log_file_generate = log_directory + "/generate.log" self._generate_mg_process( mg_directory, temp_directory, proc_card_file, mg_process_directory, ufo_model_directory=ufo_model_directory, initial_command=initial_command, log_file=log_file_generate, ) # Make MadMiner folders create_missing_folders([ mg_process_directory + "/madminer", mg_process_directory + "/madminer/cards", mg_process_directory + "/madminer/scripts", ]) # Loop over settings i = 0 results = [] for run_card_file in run_card_files: for sample_benchmark in sample_benchmarks: # Files script_file = "madminer/scripts/run_{}.sh".format(i) log_file_run = "run_{}.log".format(i) mg_commands_filename = "/madminer/cards/mg_commands_{}.dat".format( i) param_card_file = "/madminer/cards/param_card_{}.dat".format(i) reweight_card_file = "/madminer/cards/reweight_card_{}.dat".format( i) new_pythia8_card_file = None if pythia8_card_file is not None: new_pythia8_card_file = "/madminer/cards/pythia8_card_{}.dat".format( i) new_run_card_file = None if run_card_file is not None: new_run_card_file = "/madminer/cards/run_card_{}.dat".format( i) logging.info("Run %s", i) logging.info(" Sampling from benchmark: %s", sample_benchmark) logging.info(" Original run card: %s", run_card_file) logging.info(" Original Pythia8 card: %s", pythia8_card_file) logging.info(" Copied run card: %s", new_run_card_file) logging.info(" Copied Pythia8 card: %s", new_pythia8_card_file) logging.info(" Param card: %s", param_card_file) logging.info(" Reweight card: %s", reweight_card_file) logging.info(" Log file: %s", log_file_run) # Creat param and reweight cards self._export_cards( param_card_template_file, mg_process_directory, sample_benchmark=sample_benchmark, param_card_filename=mg_process_directory + "/" + param_card_file, reweight_card_filename=mg_process_directory + "/" + reweight_card_file, ) # Copy run and Pythia cards if run_card_file is not None: copy_file(run_card_file, mg_process_directory + "/" + new_run_card_file) if pythia8_card_file is not None: copy_file( pythia8_card_file, mg_process_directory + "/" + new_pythia8_card_file) # Run MG and Pythia if only_prepare_script: result = self._prepare_mg_and_pythia( mg_process_directory, proc_card_filename_from_mgprocdir=mg_commands_filename, run_card_file_from_mgprocdir=new_run_card_file, param_card_file_from_mgprocdir=param_card_file, reweight_card_file_from_mgprocdir=reweight_card_file, pythia8_card_file_from_mgprocdir=new_pythia8_card_file, is_background=is_background, script_file_from_mgprocdir=script_file, initial_command=initial_command, log_dir=log_directory, log_file_from_logdir=log_file_run, ) results.append(result) else: self._run_mg_and_pythia( mg_directory, mg_process_directory, mg_process_directory + "/" + mg_commands_filename, mg_process_directory + "/" + new_run_card_file, mg_process_directory + "/" + param_card_file, mg_process_directory + "/" + reweight_card_file, # mg_process_directory + "/" + new_pythia8_card_file, is_background=is_background, initial_command=initial_command, log_file=log_directory + "/" + log_file_run, ) i += 1 # Master shell script if only_prepare_script: master_script_filename = "{}/madminer/run.sh".format( mg_process_directory) placeholder_definition = r"mgdir=${1:-" + mg_directory + r"}" + "\n" placeholder_definition += r"mgprocdir=${2:-" + mg_process_directory + r"}" + "\n" placeholder_definition += r"mmlogdir=${3:-" + log_directory + r"}" commands = "\n".join(results) script = ( "#!/bin/bash\n\n# Master script to generate events for MadMiner\n\n" + "# Usage: run.sh [MG_directory] [MG_process_directory] [log_directory]\n\n" + "{}\n\n{}").format(placeholder_definition, commands) with open(master_script_filename, "w") as file: file.write(script) make_file_executable(master_script_filename) logging.info( "To generate events, please run:\n\n %s [MG_directory] [MG_process_directory] [log_dir]\n\n", master_script_filename, )
def _prepare_mg_and_pythia( mg_process_directory, proc_card_filename_from_mgprocdir=None, run_card_file_from_mgprocdir=None, param_card_file_from_mgprocdir=None, reweight_card_file_from_mgprocdir=None, pythia8_card_file_from_mgprocdir=None, is_background=False, script_file_from_mgprocdir=None, initial_command=None, log_dir=None, log_file_from_logdir=None, ): """ Prepares a bash script that will start the event generation. Instead of this low-level function, it is recommended to use `run` or `run_multiple`. Parameters ---------- mg_process_directory : str Path to the MG process directory. proc_card_filename_from_mgprocdir : str or None, optional Filename for the MG command card that will be generated, relative from mg_process_directory. If None, a default filename in the MG process directory will be chosen. param_card_file_from_mgprocdir : str or None, optional Path to the MadGraph run card, relative from mg_process_directory. If None, the card present in the process folder is used. Default value: None. param_card_file_from_mgprocdir : str or None, optional Path to the MadGraph run card, relative from mg_process_directory. If None, the card present in the process folder is used. Default value: None. reweight_card_file_from_mgprocdir : str or None, optional Path to the MadGraph reweight card, relative from mg_process_directory. If None, the card present in the process folder is used. Default value: None. pythia8_card_file_from_mgprocdir : str or None, optional Path to the MadGraph Pythia8 card, relative from mg_process_directory. If None, Pythia is not run. Default value: None. is_background : bool, optional Should be True for background processes, i.e. process in which the differential cross section does not depend on the parameters (and would be the same for all benchmarks). In this case, no reweighting is run, which can substantially speed up the event generation. Default value: False. script_file_from_mgprocdir : str or None, optional This sets where the shell script to run MG and Pythia is generated, relative from mg_process_directory. If None, a default filename in `mg_process_directory/madminer` is used. Default value: None. initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). Default value: None. log_file_from_logdir : str or None, optional Path to a log file in which the MadGraph output is saved, relative from the default log directory. Default value: None. Returns ------- bash_script_call : str How to call this script. """ # Preparations create_missing_folders([mg_process_directory, log_dir]) if proc_card_filename_from_mgprocdir is not None: create_missing_folders([ os.path.dirname(mg_process_directory + "/" + proc_card_filename_from_mgprocdir) ]) # Prepare run... logging.info("Preparing script to run MadGraph and Pythia in %s", mg_process_directory) return prepare_run_mg_pythia( mg_process_directory, proc_card_filename_from_mgprocdir=proc_card_filename_from_mgprocdir, run_card_file_from_mgprocdir=run_card_file_from_mgprocdir, param_card_file_from_mgprocdir=param_card_file_from_mgprocdir, reweight_card_file_from_mgprocdir=reweight_card_file_from_mgprocdir, pythia8_card_file_from_mgprocdir=pythia8_card_file_from_mgprocdir, is_background=is_background, script_file_from_mgprocdir=script_file_from_mgprocdir, initial_command=initial_command, log_file_from_logdir=log_file_from_logdir, )
def _run_mg_and_pythia( mg_directory, mg_process_directory, proc_card_filename=None, run_card_file=None, param_card_file=None, reweight_card_file=None, pythia8_card_file=None, is_background=False, initial_command=None, log_file=None, ): """ Calls MadGraph to generate events. Instead of this low-level function, it is recommended to use `run` or `run_multiple`. Parameters ---------- mg_directory : str Path to the MadGraph 5 base directory. mg_process_directory : str Path to the MG process directory. proc_card_filename : str or None, optional Filename for the MG command card that will be generated. If None, a default filename in the MG process directory will be chosen. run_card_file : str or None, optional Path to the MadGraph run card. If None, the card present in the process folder is used. Default value: None) param_card_file : str or None, optional Path to the MadGraph run card. If None, the card present in the process folder is used. Default value: None) reweight_card_file : str or None, optional Path to the MadGraph reweight card. If None, the card present in the process folder is used. (Default value = None) pythia8_card_file : str or None, optional Path to the MadGraph Pythia8 card. If None, Pythia is not run. Default value: None. is_background : bool, optional Should be True for background processes, i.e. process in which the differential cross section does not depend on the parameters (and would be the same for all benchmarks). In this case, no reweighting is run, which can substantially speed up the event generation. Default value: False. initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). Default value: None. log_file : str or None, optional Path to a log file in which the MadGraph output is saved. Default value: None. Returns ------- None """ # Preparations create_missing_folders( [mg_process_directory, os.path.dirname(log_file)]) if proc_card_filename is not None: create_missing_folders([os.path.dirname(proc_card_filename)]) # Just run it already logging.info("Starting MadGraph and Pythia in %s", mg_process_directory) run_mg_pythia( mg_directory, mg_process_directory, proc_card_filename, run_card_file, param_card_file, reweight_card_file, pythia8_card_file, is_background=is_background, initial_command=initial_command, log_file=log_file, )
def _generate_mg_process( mg_directory, temp_directory, proc_card_file, mg_process_directory, ufo_model_directory=None, log_file=None, initial_command=None, ): """ Calls MadGraph to create the process folder. Instead of this low-level function, it is recommended to use `run` or `run_multiple`. Parameters ---------- mg_directory : str Path to the MadGraph 5 directory. temp_directory : str Path to a directory for temporary files. proc_card_file : str Path to the process card that tells MadGraph how to generate the process. mg_process_directory : str Path to the MG process directory. ufo_model_directory : str or None, optional Path to a UFO model that is not yet installed. It will be copied to the MG directory before the process card is executed. Default value: None. initial_command : str or None, optional Initial bash commands that have to be executed before MG is run (e.g. to load the correct virtual environment). Default value: None. log_file : str or None, optional Path to a log file in which the MadGraph output is saved. Default value: None. Returns ------- None """ logging.info("Generating MadGraph process folder from %s at %s", proc_card_file, mg_process_directory) create_missing_folders( [temp_directory, mg_process_directory, os.path.dirname(log_file)]) if ufo_model_directory is not None: copy_ufo_model(ufo_model_directory, mg_directory) generate_mg_process( mg_directory, temp_directory, proc_card_file, mg_process_directory, initial_command=initial_command, log_file=log_file, )
def reweight_existing_sample( self, mg_process_directory, run_name, param_card_template_file, sample_benchmark, reweight_benchmarks=None, only_prepare_script=False, log_directory=None, temp_directory=None, initial_command=None, ): """ High-level function that adds the weights required for MadMiner to an existing sample. If `only_prepare_scripts=True`, the event generation is not run directly, but a bash script is created in `<process_folder>/madminer/run.sh` that will start the event generation with the correct settings. Currently does not support adding systematics. Parameters ---------- mg_process_directory : str Path to the MG process directory. If None, MadMiner uses ./MG_process. run_name : str Run name. param_card_template_file : str Path to a param card that will be used as template to create the appropriate param cards for these runs. sample_benchmark : str The name of the benchmark used to generate this sample. reweight_benchmarks : list of str or None Lists the names of benchmarks to which the sample should be reweighted. If None, all benchmarks (except sample_benchmarks) are used. only_prepare_script : bool, optional If True, the event generation is not started, but instead a run.sh script is created in the process directory. Default value: False. log_directory : str or None, optional Directory for log files with the MadGraph output. If None, ./logs is used. Default value: None. initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). Default value: None. Returns ------- None """ # TODO: check that we don't reweight to benchmarks that already have weights in the LHE file # TODO: add systematics # Defaults if log_directory is None: log_directory = "./logs" # Make MadMiner folders create_missing_folders([ mg_process_directory + "/madminer", mg_process_directory + "/madminer/cards", mg_process_directory + "/madminer/scripts", ]) # Files script_file = "madminer/scripts/run_reweight.sh" log_file_run = "reweight.log" reweight_card_file = "/madminer/cards/reweight_card_reweight.dat" # Missing benchmarks missing_benchmarks = OrderedDict() for benchmark in reweight_benchmarks: missing_benchmarks[benchmark] = self.benchmarks[benchmark] # Inform user logger.info("Reweighting setup") logger.info(" Originally sampled from benchmark: %s", sample_benchmark) logger.info(" Now reweighting to benchmarks: %s", reweight_benchmarks) logger.info(" Reweight card: %s", reweight_card_file) logger.info(" Log file: %s", log_file_run) # Create param and reweight cards self._export_cards( param_card_template_file, mg_process_directory, sample_benchmark=sample_benchmark, reweight_card_filename=mg_process_directory + "/" + reweight_card_file, include_param_card=False, benchmarks=missing_benchmarks, ) # Run reweighting if only_prepare_script: call_instruction = setup_mg_reweighting_with_scripts( mg_process_directory, run_name=run_name, reweight_card_file_from_mgprocdir=reweight_card_file, script_file_from_mgprocdir=script_file, initial_command=initial_command, log_dir=log_directory, log_file_from_logdir=log_file_run, ) logger.info("To generate events, please run:\n\n %s \n\n", call_instruction) else: run_mg_reweighting( mg_process_directory, run_name=run_name, reweight_card_file=mg_process_directory + "/" + reweight_card_file, initial_command=initial_command, log_file=log_directory + "/" + log_file_run, ) logger.info( "Finished running reweighting! Please check that events were succesfully reweighted in the following " "folder:\n\n %s/Events/%s \n\n", mg_process_directory, run_name, )
def generate_mg_process( mg_directory, temp_directory, proc_card_file, mg_process_directory, ufo_model_directory=None, log_file=None, initial_command=None, python_executable=None, ): """ Calls MadGraph to create the process folder. Parameters ---------- mg_directory : str Path to the MadGraph 5 directory. temp_directory : str Path to a directory for temporary files. proc_card_file : str Path to the process card that tells MadGraph how to generate the process. mg_process_directory : str Path to the MG process directory. ufo_model_directory : str or None, optional Path to a UFO model that is not yet installed. It will be copied to the MG directory before the process card is executed. Default value: None. initial_command : str or None, optional Initial bash commands that have to be executed before MG is run (e.g. to load the correct virtual environment). Default value: None. log_file : str or None, optional Path to a log file in which the MadGraph output is saved. Default value: None. python_executable : None or str, optional Overwrites the default Python executable Returns ------- None """ # Preparations logger.info("Generating MadGraph process folder from %s at %s", proc_card_file, mg_process_directory) create_missing_folders( [temp_directory, mg_process_directory, os.path.dirname(log_file)]) if ufo_model_directory is not None: copy_ufo_model(ufo_model_directory, mg_directory) # MG commands temp_proc_card_file = f"{temp_directory}/generate.mg5" shutil.copyfile(proc_card_file, temp_proc_card_file) with open(temp_proc_card_file, "a") as myfile: myfile.write(f"\n") myfile.write(f"\n") myfile.write(f"output {mg_process_directory}") # Call specific initial command and Python binary initial_command = f"{initial_command}; " if initial_command is not None else "" python_binary = f"{python_executable} " if python_executable is not None else "" command = f"{initial_command}{python_binary}{mg_directory}/bin/mg5_aMC {temp_proc_card_file}" logger.info(f"Calling MadGraph: {command}") _ = call_command(cmd=command, log_file=log_file)
def run_multiple( self, mg_directory, proc_card_file, param_card_template_file, run_card_files, mg_process_directory=None, pythia8_card_file=None, configuration_file=None, sample_benchmarks=None, is_background=False, only_prepare_script=False, ufo_model_directory=None, log_directory=None, temp_directory=None, initial_command=None, systematics=None, order="LO", python_executable=None, ): """ High-level function that creates the the MadGraph process, all required cards, and prepares or runs the event generation for multiple combinations of run_cards or importance samplings (`sample_benchmarks`). If `only_prepare_scripts=True`, the event generation is not run directly, but a bash script is created in `<process_folder>/madminer/run.sh` that will start the event generation with the correct settings. Parameters ---------- mg_directory : str Path to the MadGraph 5 base directory. proc_card_file : str Path to the process card that tells MadGraph how to generate the process. param_card_template_file : str Path to a param card that will be used as template to create the appropriate param cards for these runs. run_card_files : list of str Paths to the MadGraph run card. mg_process_directory : str or None, optional Path to the MG process directory. If None, MadMiner uses ./MG_process. Default value: None. pythia8_card_file : str, optional Path to the MadGraph Pythia8 card. If None, the card present in the process folder is used. Default value: None. configuration_file : str, optional Path to the MadGraph me5_configuration card. If None, the card present in the process folder is used. Default value: None. sample_benchmarks : list of str or None, optional Lists the names of benchmarks that should be used to sample events. A different sampling does not change the expected differential cross sections, but will change which regions of phase space have many events (small variance) or few events (high variance). If None, a run is started for each of the benchmarks, which should map out all regions of phase space well. Default value: None. is_background : bool, optional Should be True for background processes, i.e. process in which the differential cross section does not depend on the parameters (i.e. is the same for all benchmarks). In this case, no reweighting is run, which can substantially speed up the event generation. Default value: False. only_prepare_script : bool, optional If True, the event generation is not started, but instead a run.sh script is created in the process directory. Default value: False. ufo_model_directory : str or None, optional Path to an UFO model directory that should be used, but is not yet installed in mg_directory/models. The model will be copied to the MadGraph model directory before the process directory is generated. (Default value = None) log_directory : str or None, optional Directory for log files with the MadGraph output. If None, ./logs is used. Default value: None. temp_directory : str or None, optional Path to a temporary directory. If None, a system default is used. Default value: None. initial_command : str or None, optional Initial shell commands that have to be executed before MG is run (e.g. to load a virtual environment). If not specified and `python2_override` is True, it adds the user-installed Python2 binaries to the PATH. Default value: None. systematics : None or list of str, optional If list of str, defines which systematics are used for these runs. order : 'LO' or 'NLO', optional Differentiates between LO and NLO order runs. Minor changes to writing, reading and naming cards. Default value: 'LO' python_executable : None or str, optional Provides a path to the Python executable that should be used to call MadMiner. Default: None. Returns ------- None """ # Defaults if mg_process_directory is None: mg_process_directory = "./MG_process" if temp_directory is None: temp_directory = tempfile.gettempdir() if log_directory is None: log_directory = "./logs" if sample_benchmarks is None: sample_benchmarks = [benchmark for benchmark in self.benchmarks] # This snippet is useful when using virtual envs. # (Derives from a Python2 - Python3 issue). # Ref: https://github.com/diana-hep/madminer/issues/422 if python_executable and initial_command is None: logger.info(f"Adding {python_executable} bin folder to PATH") binary_path = os.popen(f"command -v {python_executable}").read().strip() binary_folder = os.path.dirname(binary_path) initial_command = f"export PATH={binary_folder}:$PATH" logger.info(f"Using Python executable {binary_path}") # Generate process folder log_file_generate = f"{log_directory}/generate.log" generate_mg_process( mg_directory, temp_directory, proc_card_file, mg_process_directory, ufo_model_directory=ufo_model_directory, initial_command=initial_command, log_file=log_file_generate, python_executable=python_executable, ) # Make MadMiner folders create_missing_folders( [ f"{mg_process_directory}/madminer", f"{mg_process_directory}/madminer/cards", f"{mg_process_directory}/madminer/scripts", ] ) # Systematics if systematics is None: systematics_used = self.systematics else: systematics_used = OrderedDict() for key in systematics: systematics_used[key] = self.systematics[key] # Loop over settings i = 0 mg_scripts = [] for run_card_file in run_card_files: for sample_benchmark in sample_benchmarks: # Files script_file = f"madminer/scripts/run_{i}.sh" log_file_run = f"run_{i}.log" mg_commands_filename = f"madminer/cards/mg_commands_{i}.dat" param_card_file = f"madminer/cards/param_card_{i}.dat" reweight_card_file = f"madminer/cards/reweight_card_{i}.dat" new_pythia8_card_file = None if pythia8_card_file is not None: new_pythia8_card_file = f"madminer/cards/pythia8_card_{i}.dat" new_run_card_file = None if run_card_file is not None: new_run_card_file = f"madminer/cards/run_card_{i}.dat" new_configuration_file = None if configuration_file is not None: new_configuration_file = f"madminer/cards/me5_configuration_{i}.txt" logger.info("Run %s", i) logger.info(" Sampling from benchmark: %s", sample_benchmark) logger.info(" Original run card: %s", run_card_file) logger.info(" Original Pythia8 card: %s", pythia8_card_file) logger.info(" Original config card: %s", configuration_file) logger.info(" Copied run card: %s", new_run_card_file) logger.info(" Copied Pythia8 card: %s", new_pythia8_card_file) logger.info(" Copied config card: %s", new_configuration_file) logger.info(" Param card: %s", param_card_file) logger.info(" Reweight card: %s", reweight_card_file) logger.info(" Log file: %s", log_file_run) # Check input if run_card_file is None and self._check_pdf_or_scale_variation(systematics_used): logger.warning( "Warning: No run card given, but PDF or scale variation set up. The correct systematics" " settings are not set automatically. Make sure to set them correctly!" ) # Create param and reweight cards self._export_cards( param_card_template_file, mg_process_directory, sample_benchmark=sample_benchmark, param_card_filename=f"{mg_process_directory}/{param_card_file}", reweight_card_filename=f"{mg_process_directory}/{reweight_card_file}", ) # Create run card if run_card_file is not None: export_run_card( template_filename=run_card_file, run_card_filename=f"{mg_process_directory}/{new_run_card_file}", systematics=systematics_used, order=order, ) # Copy Pythia card if pythia8_card_file is not None: copy_file(pythia8_card_file, f"{mg_process_directory}/{new_pythia8_card_file}") # Copy Configuration card if configuration_file is not None: copy_file(configuration_file, f"{mg_process_directory}/{new_configuration_file}") # Run MG and Pythia if only_prepare_script: mg_script = setup_mg_with_scripts( mg_process_directory, proc_card_filename_from_mgprocdir=mg_commands_filename, run_card_file_from_mgprocdir=new_run_card_file, param_card_file_from_mgprocdir=param_card_file, reweight_card_file_from_mgprocdir=reweight_card_file, pythia8_card_file_from_mgprocdir=new_pythia8_card_file, configuration_file_from_mgprocdir=new_configuration_file, is_background=is_background, script_file_from_mgprocdir=script_file, initial_command=initial_command, log_dir=log_directory, log_file_from_logdir=log_file_run, python_executable=python_executable, order=order, ) mg_scripts.append(mg_script) else: run_mg( mg_directory, mg_process_directory, f"{mg_process_directory}/{mg_commands_filename}", f"{mg_process_directory}/{new_run_card_file}", f"{mg_process_directory}/{param_card_file}", f"{mg_process_directory}/{reweight_card_file}", None if new_pythia8_card_file is None else f"{mg_process_directory}/{new_pythia8_card_file}", None if new_configuration_file is None else f"{mg_process_directory}/{new_configuration_file}", is_background=is_background, initial_command=initial_command, log_file=f"{log_directory}/{log_file_run}", python_executable=python_executable, order=order, ) i += 1 n_runs_total = i # Master shell script if only_prepare_script: master_script_filename = f"{mg_process_directory}/madminer/run.sh" create_master_script( log_directory, master_script_filename, mg_directory, mg_process_directory, mg_scripts, ) logger.info( "To generate events, please run:\n\n %s [MG_directory] [MG_process_directory] [log_dir]\n\n", master_script_filename, ) else: expected_event_files = [f"{mg_process_directory}/Events/run_{(i+1):02d}" for i in range(n_runs_total)] expected_event_files = "\n".join(expected_event_files) logger.info( "Finished running MadGraph! Please check that events were succesfully generated in the following " "folders:\n\n%s\n\n", expected_event_files, )