コード例 #1
0
    def __init__(self, config, GS_dir):
        """ Load YAML config into a dictionary and assign values to variables for cleanliness """
        _config = load_yaml_config(config, quiet=True)

        # Reset text colours after colourful print statements
        init(autoreset=True)

        self.model_name = _config['model_name']
        self.m_med = _config['m_med']
        self.m_d = _config['m_d']
        self.n_f = _config['n_f']
        self.r_inv = _config['r_inv']
        self.x_sec_mg = _config['x_sec_mg']
        self.alpha_d = _config['alpha_d']
        self.process_type = _config['process_type']
        self.year = _config['year']

        self.GS_dir = GS_dir

        # Run everything
        print(Fore.CYAN + "Writing gen fragment...")
        self.set_dark_params()
        self.get_lambda_d()
        self.get_xsec()
        self.get_pythia_info()
        self.write_fragment()
コード例 #2
0
def xsec_from_dict(in_file, m_med):
    """
    Get cross section from yaml dictionary
    """
    xsec_dict = load_yaml_config(in_file, quiet=True)
    try:
        x_sec = xsec_dict[m_med]
    except KeyError:
        if m_med < min(xsec_dict.keys()) or m_med > max(xsec_dict.keys()):
            raise ValueError(
                "m_med = {} is outside the range of the dictionary in '{}'".
                format(m_med, in_file))
        else:
            # Cross sections given in increments of 100 GeV. Round m_med if required
            x_sec = xsec_dict[int(round(m_med, -2))]
    return x_sec
コード例 #3
0
def main(config, resub=False, mode='batch'):
    # Load YAML config into a dictionary and assign values to variables for cleanliness
    input_params = load_yaml_config(config)

    # Set variables from config file
    process_type = input_params['process_type']
    m_med = input_params['m_med']
    n_events = input_params['n_events']
    n_jobs = input_params['n_jobs']
    m_d = input_params['m_d']
    r_inv = input_params['r_inv']
    alpha_d = input_params['alpha_d']
    year = input_params['year']

    # Check arguments in config file
    basic_checks(input_params)

    # Set process-specific variables
    if 's-channel' in process_type:
        med_type = 'Zp'
        model_prefix = 'SVJ_s'
        template_prefix = 'DMsimp_SVJ_s_spin1'
    elif 't-channel' in process_type:
        med_type = 'Phi'
        model_prefix = 'SVJ_t'
        template_prefix = 'DMsimp_SVJ_t'

    default_model_dir = os.path.join(os.environ['SVJ_MODELS_DIR'], template_prefix+'_editTemplate')
    model_name = '{prefix}_{year}_m{med}-{m_med}_mDQ-{m_d}_rinv-{rinv}_aD-{alphad}'.format(
        rinv=str(r_inv).replace('.', 'p'), alphad=str(alpha_d).replace('.', 'p'),  # MadGraph doesn't like '.' in the model name
        prefix=model_prefix, med=med_type, **input_params)
    total_events = n_events * n_jobs

    # Remove failed gridpack for model if resubmitted
    if resub:
        print(Fore.CYAN + "Removing failed gridpack and resubmitting...")
        for file in glob.glob(os.path.join(os.environ['MG_GENPROD_DIR'], model_name+'*')):
            try:
                if os.path.isfile(file):
                    os.remove(file)
                elif os.path.isdir(file):
                    shutil.rmtree(file)
            except OSError as e:
                print("Error: {0} - {1}.".format(e.filename, e.strerror))

    # If required, append config file with new parameters for simplicity in future steps
    with open(config, 'r+') as f:
        print(Fore.CYAN + "Updating config file with new parameters...")
        original_str = f.readlines()
        # Delete contents of file and update
        f.seek(0)
        f.truncate()
        # Strip model name and total events if they've changed since last use of config, and also blank lines
        for line in original_str:
            if any(line.startswith(x) for x in ['model_name:', 'total_events:', '\n']):
                continue
            else:
                f.write(line)
        # Write new parameters at the end of the file
        f.write("\nmodel_name: {}\ntotal_events: {}\n".format(model_name, total_events))

    new_model_dir = os.path.join(os.environ['SVJ_MODELS_DIR'], model_name)
    if os.path.exists(new_model_dir):
        print("Model of type {} with parameters m_med = {}, m_d = {} already exists!".format(process_type, m_med, m_d))
    else:
        # Copy model files to new directory and change relevant parameters according to config
        print(Fore.CYAN + "Copying template model...")
        shutil.copytree(default_model_dir, new_model_dir)
        # Read the parameters file (containing the dark particle masses) in the new model directory
        with open(os.path.join(new_model_dir, 'parameters.py'), 'r+') as f:
            old_params = Template(f.read())
            # Fill placeholders with values chosen by user
            new_params = old_params.substitute(dark_quark_mass=str(m_d), mediator_mass=str(m_med))
            f.seek(0)
            f.truncate()
            f.write(new_params)
        print(Fore.MAGENTA + "New parameters written in model files!")

    # Write param_card text file
    call('python {}'.format(os.path.join(new_model_dir, 'write_param_card.py')), shell=True)

    input_cards_dir = os.path.join(os.environ['SVJ_MG_INPUT_DIR'], model_name+"_input")
    # Create directory to store input cards and model files for MadGraph
    if not os.path.exists(input_cards_dir):
        os.mkdir(input_cards_dir)
    else:
        print("Directory containing MadGraph input cards exists! No need to create it.")
        # Remove previous input cards in case, e.g., n_events has changed
        for old_file in glob.glob(os.path.join(input_cards_dir, '*.dat')):
            os.remove(old_file)

    # Copy MadGraph input files from template card directory
    # Even if input_cards_dir existed before, copy the template files over in case parameters have changed
    for in_file in glob.glob(os.path.join(os.environ['SVJ_MG_INPUT_DIR'], template_prefix+'_input_template/*.dat')):
        # Get the suffix of the template card for specifying the basename in the dest. path
        card_type = re.search("(?<={0})(\w+).dat".format(template_prefix), in_file).group(0)
        shutil.copy(in_file, os.path.join(input_cards_dir, model_name+card_type))

    # In input files, fill replacement fields with values chosen by user
    for modelFile in glob.glob(os.path.join(input_cards_dir, '*.dat')):
        with open(modelFile, 'r+') as mg_card:
            old_params = mg_card.read()
            # Make sure there are no curly braces in the input cards except those containing the replacement fields
            new_params = old_params.format(modelName=model_name, totalEvents=total_events, lhaid=lhaID_dict[year])
            mg_card.seek(0)
            mg_card.truncate()
            mg_card.write(new_params)
        print(Fore.MAGENTA + "Parameters written for input card", os.path.basename(modelFile))

    # Zip up model directory, specifying basedir to zip enclosing folder, not just files
    shutil.make_archive(os.path.join(input_cards_dir, model_name), 'tar', os.environ['SVJ_MODELS_DIR'], model_name)
    print(Fore.MAGENTA + "Copied model files to input directory!")

    # Require relative path between MG input files and genproductions' gridpack generation script
    rel_cards_dir = os.path.relpath(input_cards_dir, os.environ['MG_GENPROD_DIR'])

    # Run the gridpack generation
    call("{}/runGridpackGeneration.sh {} {} {}".format(os.path.dirname(os.path.realpath(__file__)), model_name, rel_cards_dir, mode), shell=True)
コード例 #4
0
def main(config):
    # Load YAML config into a dictionary and assign values to variables for cleanliness
    input_params = load_yaml_config(config)

    model_name = input_params['model_name']
    total_events = input_params['total_events']
    n_jobs = input_params['n_jobs']
    out_split_lhe = input_params['lhe_file_path']
    process_type = input_params['process_type']

    # Check arguments in config file
    basic_checks(input_params)

    # Set up some path variables for use later
    genprod_dir = os.environ['MG_GENPROD_DIR']
    default_gridpack_dir = os.path.join(genprod_dir, model_name)
    lhe_gen_dir = os.path.join(default_gridpack_dir, model_name + '_gridpack',
                               'work', 'gridpack')
    gridpack_outdir = os.path.join(os.environ['SVJ_MG_FILES_DIR'], 'gridpacks')

    # Get cross section from gridpack generation log file
    with open(os.path.join(lhe_gen_dir, 'gridpack_generation.log'), 'r') as f:
        log_str = f.read()
        x_sec_mg = re.search("(?<=Cross-section :   )(\d*.\d+)",
                             log_str).group(0)

    # Append cross section to config file if not included already
    with open(config, 'r+') as f:
        config_str = f.read()
        if str(x_sec_mg) not in config_str:
            print(
                Fore.CYAN +
                "Appending config file with cross section as calculated by MadGraph..."
            )
            f.seek(0)
            config_lines = f.readlines()
            f.seek(0)
            f.truncate()
            for i in config_lines:
                if i.startswith('x_sec_mg'):
                    continue
                else:
                    f.write(i)
            f.write("x_sec_mg: {}\n".format(x_sec_mg))

    # Copy gridpack tarball to new directory
    for tarball in glob.glob(os.path.join(genprod_dir, model_name + '*.xz')):
        print(Fore.CYAN + "Copying {} to {}/".format(os.path.basename(tarball),
                                                     gridpack_outdir))
        shutil.copyfile(
            tarball, os.path.join(gridpack_outdir, os.path.basename(tarball)))
        os.remove(tarball)

    # Run the script produced with the gridpack to get the LHE file out and copy to gridpacks dir
    seed = random.randint(0, 1000000)
    call("cd {}; ./runcmsgrid.sh {} {}".format(lhe_gen_dir, total_events,
                                               seed),
         shell=True)
    in_lhe = os.path.join(gridpack_outdir, model_name + '_LHE.lhe')
    shutil.copyfile(os.path.join(lhe_gen_dir, 'cmsgrid_final.lhe'), in_lhe)

    # Delete untarred gridpack as it takes up unnecessary space
    shutil.rmtree(default_gridpack_dir)
    print(Fore.MAGENTA + "Removed untarred version of gridpack!")

    # Change PDGIDs for dark particles in preparation for hadronisation
    call('{}/utils/pid_change.sh {}'.format(os.environ['SVJ_TOP_DIR'], in_lhe),
         shell=True)

    # Split the LHE file, the output files being stored in the current directory
    print(Fore.CYAN + "Splitting LHE file...")
    splitLHE(inputFile=in_lhe,
             outFileNameBase=model_name + '_split',
             numFiles=n_jobs)
    os.remove(in_lhe)

    # Copy the split LHE files to directory specified by user
    if not os.path.exists(out_split_lhe):
        os.mkdir(out_split_lhe)
    for split_file in glob.glob(
            os.path.join(os.getcwd(), model_name + '_split*.lhe')):
        shutil.copy(split_file, out_split_lhe)
        os.remove(split_file)
    print(Fore.MAGENTA + "Split LHE files moved to {}".format(out_split_lhe))
コード例 #5
0
def main(config):
    # Define variable for directory of script
    this_dir = os.path.dirname(os.path.realpath(__file__))

    # Load YAML config into a dictionary and assign values to variables for cleanliness
    config = os.path.abspath(config)
    input_params = load_yaml_config(config)

    work_space = input_params['work_space']
    lhe_file_path = input_params['lhe_file_path']
    n_events = input_params['n_events']
    n_jobs = input_params['n_jobs']
    model_name = input_params['model_name']
    year = input_params['year']

    # Check arguments in config file
    thorough_checks(input_params)

    # Make a list of split LHE files for checks
    lhe_files = []
    for file in os.listdir(lhe_file_path):
        if '{}_split'.format(model_name) in file and file.endswith('.lhe'):
            lhe_files.append(os.path.join(lhe_file_path, file))

    if n_jobs > len(lhe_files):
        sys.exit(
            'Number of jobs exceeds number of LHE files in directory. Check and try again.'
        )

    if not os.path.exists(work_space):
        print(Fore.CYAN + "Work space doesn't exist. Creating it now...")
        os.makedirs(work_space)

    shutil.copy(
        os.path.join(os.environ['SVJ_TOP_DIR'],
                     'pileup_filelist_{}.txt'.format(year)), work_space)

    # Initialise proxy of grid certificate if required
    if 'root://' in lhe_file_path and 'X509_USER_PROXY' not in os.environ.keys(
    ):
        grid_cert_path = '{}/x509up_u{}'.format(work_space, os.getuid())
        call('voms-proxy-init --voms cms --valid 168:00 --out {}'.format(
            grid_cert_path),
             shell=True)
        os.environ['X509_USER_PROXY'] = grid_cert_path

    # Get CMSSW versions and architecture info
    cmssw_info = CmsswInfo(year)
    cmssw_info.initialise_envs(location=work_space)

    if os.getcwd() != this_dir:
        os.chdir(this_dir)

    # Create additional directories
    gen_frag_dir = os.path.join(work_space, cmssw_info.gensim['version'],
                                'src', 'Configuration', 'GenProduction',
                                'python')
    extra_fullsim_dirs = [
        gen_frag_dir,
        '{}/logs/{}'.format(work_space, model_name),
        '{}/output'.format(work_space),
        '{}/submission_scripts/{}'.format(work_space, model_name),
    ]
    for dir in extra_fullsim_dirs:
        if not os.path.exists(dir):
            os.makedirs(dir)

    # Create the gen fragment
    gen_frag = os.path.basename(
        WriteGenSimFragment(config, gen_frag_dir).out_file)

    # Compile after everything is written to ensure gen fragment can be linked to
    cmssw_info.compile_env(location=work_space,
                           version=cmssw_info.gensim['version'],
                           arch=cmssw_info.gensim['arch'])

    # Create scripts to hadd output files and resubmit failed jobs
    write_combine_script(work_space, model_name, cmssw_info.nano['version'])
    write_resubmitter_script(work_space, model_name, n_jobs)
    write_cleanup_script(work_space, model_name)

    lhe_base = os.path.join(lhe_file_path, '{}_split'.format(model_name))
    sub_args = (work_space, gen_frag, lhe_base, model_name, n_events, year)
    # Write a single job file to submit everything at once
    main_job = HTCondorJob(*sub_args, queue=n_jobs)
    call('condor_submit {}'.format(main_job.job_file), shell=True)
    print(Fore.MAGENTA + "Jobs submitted. Monitor them with 'condor_q $USER'")

    print(
        Fore.CYAN +
        "Writing individual job files to make resubmitting failed jobs easier..."
    )
    for seed in xrange(n_jobs):
        HTCondorJob(*sub_args, seed=seed)
コード例 #6
0
            Style.RESET_ALL)


if __name__ == '__main__':
    parser = ArgumentParser(description=__doc__,
                            formatter_class=ArgumentDefaultsHelpFormatter)
    parser.add_argument("config",
                        type=str,
                        help="Path to YAML config to parse")

    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('-b',
                       '--basic',
                       action="store_true",
                       help="Perform basic config checks")
    group.add_argument('-t',
                       '--thorough',
                       action="store_true",
                       help="Perform thorough config checks")

    args = parser.parse_args()

    print(Fore.MAGENTA + "Checking config file...", Style.RESET_ALL)
    config_dict = load_yaml_config(args.config)

    if args.basic:
        basic_checks(config_dict)
    elif args.thorough:
        thorough_checks(config_dict)
    sys.exit("Completed")
コード例 #7
0
 def __init__(self, config):
     self.config = config
     self.in_params = load_yaml_config(self.config)
     self.n_jobs = in_params['n_jobs']