diff --git a/bin/rivet-diffhepdata b/bin/rivet-diffhepdata --- a/bin/rivet-diffhepdata +++ b/bin/rivet-diffhepdata @@ -1,147 +1,147 @@ #! /usr/bin/env python """\ rivet-diffhepdata [-h|--help] [-r|--rivet_input RIVET_INPUT] [-i|--inspire_id INSPIRE_ID] [-d|--hepdata_input HEPDATA_INPUT] [-o|--output OUTPUT] [-a|--all] [-l|--lower_count LOWER_COUNT] [-u|--upper_count UPPER_COUNT] [-f|--force_download] Check compatibility of a YODA reference data file, intended for inclusion in Rivet, with the YODA file downloaded from HEPData. Specify either the INSPIRE_ID (to download the YODA file from HEPData) or the already-downloaded HEPDATA_INPUT. Make the comparison using the yodadiff script distributed with YODA (https://yoda.hepforge.org/trac/browser/bin/yodadiff). Optionally write the yodadiff output to a file OUTPUT instead of stdout. Note: If option --all is specified, check compatibility of *all* YODA reference data files, distributed with Rivet, with the YODA files downloaded from HEPData in HEPDATA_INPUT and write the yodadiff to the output directory OUTPUT. Optional arguments to loop over a range of INSPIRE IDs (for testing) and to force re-download of HEPData .yoda files. Examples: rivet-diffhepdata -r ATLAS_2017_I1614149.yoda -i 1614149 rivet-diffhepdata -r ATLAS_2017_I1614149.yoda -d HEPData-ins1614149-v2-yoda.yoda # Specify Rivet directory, HEPData and yodadiff output directories, and redirect output to a text file. rivet-diffhepdata --all -r ../Rivet/analyses -d HEPDataYoda -o YodaDiffOutput > rivet-diffhepdata-all.txt # Loop over only the first 10 INSPIRE IDs (sorted by Rivet analysis name) and force HEPData re-download. rivet-diffhepdata --all -l 1 -u 10 -f # for Rivet .yoda files located in a subdirectory of current path """ from __future__ import print_function import os, imp, glob, requests, argparse from rivet import hepdatautils parser = argparse.ArgumentParser(description='Check compatibility of YODA reference data files with HEPData for all Rivet analyses') parser.add_argument('-r', '--rivet_input', nargs=1, default=['.'], help='input YODA file (or search directory if using --all flag)') parser.add_argument('-i', '--inspire_id', nargs=1, default=[0], type=int, help='INSPIRE ID (to download the YODA file from HEPData') parser.add_argument('-d', '--hepdata_input', nargs=1, default=[None], help='input HEPData reference file/directory for downloading files') parser.add_argument('-o', '--output', nargs=1, default=[None], help='name of output file/directory to write yodadiff output') parser.add_argument('-a', '--all', action='store_true', help='check all available files, unless lower and upper count are also specified') parser.add_argument('-l', '--lower_count', nargs=1, type=int, default=[0], help='minimum count for loop over INSPIRE IDs') parser.add_argument('-u', '--upper_count', nargs=1, type=int, default=[0], help='maximum count for loop over INSPIRE IDs') parser.add_argument('-f', '--force_download', action='store_true', help='force re-download of HEPData .yoda files') args = parser.parse_args() rivet_input = args.rivet_input[0] inspire_id = args.inspire_id[0] hepdata_input = args.hepdata_input[0] output_name = args.output[0] do_all = args.all lower_count = args.lower_count[0] upper_count = args.upper_count[0] force_download = args.force_download print('Arguments specified:') print(' rivet_input={}'.format(rivet_input)) print(' inspire_id={}'.format(inspire_id)) print(' hepdata_input={}'.format(hepdata_input)) print(' output={}'.format(output_name)) print(' all={}'.format(do_all)) print(' lower_count={}'.format(lower_count)) print(' upper_count={}'.format(upper_count)) print(' force_download={}'.format(force_download)) def find(filename, path): """ Function to return first matching 'filename' by walking the directory tree top-down from 'path'. """ for root, dirs, files in os.walk(path): if filename in files: return os.path.join(root, filename) if do_all: # check multiple files if output_name == None: output_name = '.' if hepdata_input == None: hepdata_input = '.' # Create output directories if they don't already exist. if not os.path.exists(hepdata_input): os.makedirs(hepdata_input) if not os.path.exists(output_name): os.makedirs(output_name) # Get mapping between INSPIRE IDs and Rivet analysis names. response = requests.get('http://rivet.hepforge.org/analyses.json') analyses = response.json() # Loop over INSPIRE IDs and collect compatible and incompatible analyses. # Sort analyses dict by the Rivet analysis name. compatible_analyses = [] incompatible_analyses = [] for count, inspire_id in enumerate(sorted(analyses, key=analyses.get)): # Loop over a restricted range of INSPIRE IDs (useful for testing). if count + 1 < lower_count or (upper_count and count + 1 > upper_count): continue print() num_analyses = len(analyses[inspire_id]) if num_analyses != 1: compatible = False print('Multiple (or zero) Rivet analyses {} for INSPIRE ID {}.'.format(analyses[inspire_id], inspire_id)) else: analysis = analyses[inspire_id][0] yodafile = find(analysis + '.yoda', rivet_input) outfile = os.path.join(output_name, analysis + '.txt') # Check if .yoda file has already been downloaded from HEPData, otherwise download. Override if force_download. matched_files = glob.glob(os.path.join(hepdata_input, 'HEPData-ins' + inspire_id + '-v*-yoda.yoda')) if not matched_files or force_download: try: yodafile_from_hepdata = hepdatautils.download_from_hepdata(inspire_id, analysis) except: print('Download from HEPData failed for Rivet analysis {}.'.format(analysis)) if yodafile_from_hepdata: os.rename(yodafile_from_hepdata, os.path.join(hepdata_input, yodafile_from_hepdata)) - yodafile_from_hepdata = os.path.join(hepdata_directory, yodafile_from_hepdata) + yodafile_from_hepdata = os.path.join(hepdata_input, yodafile_from_hepdata) else: print('Missing YODA reference data file from HEPData for Rivet analysis {}.'.format(analysis)) else: yodafile_from_hepdata = sorted(matched_files)[-1] # sort in case of multiple versions (works for v1 up to v9) # Run yodadiff between the .yoda files from Rivet and HEPData. if yodafile: compatible = hepdatautils.compare_with_hepdata(yodafile, yodafile_from_hepdata=yodafile_from_hepdata, output=outfile) else: print('Missing YODA reference data file from Rivet for analysis {}.'.format(analysis)) compatible = False if compatible: print('YODA reference data files from Rivet and HEPData are compatible!') compatible_analyses.append(inspire_id) else: print('YODA reference data files from Rivet and HEPData are NOT compatible!') incompatible_analyses.append(inspire_id) # Print out some summary information. print() print('Compatible Rivet analyses: {}'.format([analyses[inspire_id] for inspire_id in compatible_analyses])) print('Incompatible Rivet analyses: {}'.format([analyses[inspire_id] for inspire_id in incompatible_analyses])) print() print('Of {:d} Rivet analyses in {}, {:d} ({:.1f}%) were compatible and {:d} ({:.1f}%) were incompatible.'.format( len(analyses), rivet_input, len(compatible_analyses), 100.*len(compatible_analyses)/len(analyses), len(incompatible_analyses), 100.*len(incompatible_analyses)/len(analyses))) else: # check single file only compatible = hepdatautils.compare_with_hepdata(rivet_input, inspire_id, hepdata_input, output_name) if compatible: print('YODA reference data files from Rivet and HEPData are compatible!') else: print('YODA reference data files from Rivet and HEPData are NOT compatible!')