diff --git a/bin/rivet-diffhepdata b/bin/rivet-diffhepdata --- a/bin/rivet-diffhepdata +++ b/bin/rivet-diffhepdata @@ -1,147 +1,33 @@ #! /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] +rivet-diffhepdata [-h|--help] yodafile [-i|--inspire_id INSPIRE_ID] [-d|--yodafile_from_hepdata YODAFILE_FROM_HEPDATA] [-o|--output OUTPUT] 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. +Specify either the INSPIRE_ID (to download the YODA file from HEPData) or the already-downloaded YODAFILE_FROM_HEPDATA. 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') +parser = argparse.ArgumentParser(description='Check compatibility of YODA reference data file with HEPData') +parser.add_argument('yodafile', help='name of YODA reference data file (intended for inclusion in Rivet)') +group = parser.add_mutually_exclusive_group() +group.add_argument('-i', '--inspire_id', nargs=1, default=[0], type=int, help='INSPIRE ID (to download the YODA file from HEPData') +group.add_argument('-d', '--yodafile_from_hepdata', nargs=1, default=[None], help='name of YODA file already downloaded from HEPData') +parser.add_argument('-o', '--output', nargs=1, default=[None], help='name of output file to write yodadiff output') 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)) +compatible = compare_hepdata(args.yodafile, args.inspire_id[0], args.yodafile_from_hepdata[0], args.output[0]) +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!') -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_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!') - diff --git a/bin/rivet-diffhepdata-all b/bin/rivet-diffhepdata-all new file mode 100755 --- /dev/null +++ b/bin/rivet-diffhepdata-all @@ -0,0 +1,122 @@ +#! /usr/bin/env python + +"""\ +rivet-diffhepdata-all [-h|--help] [-r|--rivet_directory RIVET_DIRECTORY] [-d|--hepdata_directory HEPDATA_DIRECTORY] [-o|--output_directory OUTPUT_DIRECTORY] [-l|--lower_count LOWER_COUNT] [-u|--upper_count UPPER_COUNT] [-f|--force_download] + +Check compatibility of YODA reference data files, distributed with Rivet, with the YODA file downloaded from HEPData. +Optional arguments to specify Rivet analyses directory and directories to store HEPData .yoda files and yodadiff output. +Optional arguments to loop over a range of INSPIRE IDs (for testing) and to force re-download of HEPData .yoda files. + +Examples: + # 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_directory', nargs=1, default=['.'], help='directory to search for Rivet .yoda files') +parser.add_argument('-d', '--hepdata_input', nargs=1, default=['.'], help='directory to store downloaded HEPData .yoda files') +parser.add_argument('-o', '--output_directory', nargs=1, default=['.'], help='directory to write yodadiff output') +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_directory = args.rivet_directory[0] +hepdata_directory = args.hepdata_directory[0] +output_name = args.output_directory[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_directory={}'.format(rivet_directory)) +print(' hepdata_directory={}'.format(hepdata_directory)) +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) + +# Create output directories if they don't already exist. +if not os.path.exists(hepdata_directory): + os.makedirs(hepdata_directory) +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_directory) + 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_directory, '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_directory, yodafile_from_hepdata)) + yodafile_from_hepdata = os.path.join(hepdata_directory, 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_directory, + len(compatible_analyses), 100.*len(compatible_analyses)/len(analyses), + len(incompatible_analyses), 100.*len(incompatible_analyses)/len(analyses))) +