|
|
|
|
|
""" |
|
|
Simple ROOT file inspector using uproot |
|
|
Usage: python inspect_root.py [options] |
|
|
|
|
|
Default data directory: /global/cfs/projectdirs/atlas/eligd/llm_for_analysis_copy/data/ |
|
|
""" |
|
|
|
|
|
import sys |
|
|
import os |
|
|
import uproot |
|
|
import numpy as np |
|
|
import argparse |
|
|
|
|
|
|
|
|
DEFAULT_DATA_DIR = '/global/cfs/projectdirs/atlas/eligd/llm_for_analysis_copy/data/' |
|
|
|
|
|
def inspect_root_file(filepath, show_stats=True, max_entries=None): |
|
|
"""Inspect a ROOT file and display its contents""" |
|
|
|
|
|
if not os.path.exists(filepath): |
|
|
print("Error: File '{}' does not exist!".format(filepath)) |
|
|
return |
|
|
|
|
|
print("Inspecting ROOT file: {}".format(filepath)) |
|
|
print("=" * 80) |
|
|
|
|
|
try: |
|
|
|
|
|
with uproot.open(filepath) as file: |
|
|
print("File opened successfully!") |
|
|
print("Keys in file: {}".format(list(file.keys()))) |
|
|
print() |
|
|
|
|
|
|
|
|
trees = [key for key in file.keys() if not key.endswith(';1') or ';' not in key] |
|
|
print("Available trees/objects: {}".format(trees)) |
|
|
print() |
|
|
|
|
|
|
|
|
tree_name = None |
|
|
if 'mini;1' in file: |
|
|
tree_name = 'mini;1' |
|
|
elif 'mini' in file: |
|
|
tree_name = 'mini' |
|
|
else: |
|
|
|
|
|
for key in file.keys(): |
|
|
if ';' in key and not key.endswith('.root'): |
|
|
tree_name = key |
|
|
break |
|
|
|
|
|
if tree_name: |
|
|
print("Inspecting tree: {}".format(tree_name)) |
|
|
tree = file[tree_name] |
|
|
|
|
|
|
|
|
num_entries = tree.num_entries |
|
|
print("Number of entries: {}".format(num_entries)) |
|
|
print("Branches: {}".format(list(tree.keys()))) |
|
|
print() |
|
|
|
|
|
if max_entries: |
|
|
num_entries = min(num_entries, max_entries) |
|
|
print("Limiting analysis to first {} entries".format(num_entries)) |
|
|
print() |
|
|
|
|
|
|
|
|
print("Branch details:") |
|
|
for branch_name in tree.keys(): |
|
|
try: |
|
|
branch = tree[branch_name] |
|
|
if hasattr(branch, 'array'): |
|
|
arr = branch.array() |
|
|
if max_entries: |
|
|
arr = arr[:max_entries] |
|
|
|
|
|
|
|
|
if hasattr(arr, 'shape'): |
|
|
print(" {}: shape={}, dtype={}".format(branch_name, arr.shape, arr.dtype)) |
|
|
else: |
|
|
|
|
|
print(" {}: type={}, value_type={}".format(branch_name, type(arr), arr.dtype if hasattr(arr, 'dtype') else 'unknown')) |
|
|
|
|
|
if len(arr) > 0: |
|
|
sample_size = min(5, len(arr)) |
|
|
print(" Sample values: {}".format(arr[:sample_size])) |
|
|
else: |
|
|
print(" {}: {}".format(branch_name, type(branch))) |
|
|
except Exception as e: |
|
|
print(" {}: Error reading - {}".format(branch_name, e)) |
|
|
print() |
|
|
|
|
|
if show_stats: |
|
|
|
|
|
print("Basic statistics for numerical branches:") |
|
|
for branch_name in tree.keys(): |
|
|
try: |
|
|
branch = tree[branch_name] |
|
|
if hasattr(branch, 'array'): |
|
|
arr = branch.array() |
|
|
if max_entries: |
|
|
arr = arr[:max_entries] |
|
|
if arr.dtype.kind in 'iufc': |
|
|
print(" {}:".format(branch_name)) |
|
|
print(" Mean: {:.3f}".format(np.mean(arr))) |
|
|
print(" Std: {:.3f}".format(np.std(arr))) |
|
|
print(" Min: {:.3f}".format(np.min(arr))) |
|
|
print(" Max: {:.3f}".format(np.max(arr))) |
|
|
except: |
|
|
pass |
|
|
else: |
|
|
print("No tree found in the file.") |
|
|
|
|
|
except Exception as e: |
|
|
print("Error opening file: {}".format(e)) |
|
|
|
|
|
def list_files_in_directory(directory): |
|
|
"""List all ROOT files in a directory""" |
|
|
if not os.path.exists(directory): |
|
|
print("Directory '{}' does not exist!".format(directory)) |
|
|
return [] |
|
|
|
|
|
root_files = [] |
|
|
for filename in os.listdir(directory): |
|
|
if filename.endswith('.root'): |
|
|
root_files.append(os.path.join(directory, filename)) |
|
|
|
|
|
return sorted(root_files) |
|
|
|
|
|
def main(): |
|
|
parser = argparse.ArgumentParser(description='Inspect ROOT files using uproot') |
|
|
parser.add_argument('filepath', nargs='?', help='Path to the ROOT file to inspect') |
|
|
parser.add_argument('--data-dir', default=DEFAULT_DATA_DIR, |
|
|
help='Default data directory (default: {})'.format(DEFAULT_DATA_DIR)) |
|
|
parser.add_argument('--list-files', action='store_true', |
|
|
help='List all ROOT files in the data directory') |
|
|
parser.add_argument('--inspect-all', action='store_true', |
|
|
help='Inspect all ROOT files in the data directory') |
|
|
parser.add_argument('--no-stats', action='store_true', |
|
|
help='Skip statistical analysis') |
|
|
parser.add_argument('--max-entries', type=int, |
|
|
help='Limit analysis to first N entries') |
|
|
|
|
|
args = parser.parse_args() |
|
|
|
|
|
if args.list_files: |
|
|
|
|
|
root_files = list_files_in_directory(args.data_dir) |
|
|
print("ROOT files in {}:".format(args.data_dir)) |
|
|
for i, filepath in enumerate(root_files, 1): |
|
|
filename = os.path.basename(filepath) |
|
|
print(" {}. {}".format(i, filename)) |
|
|
return |
|
|
|
|
|
if args.inspect_all: |
|
|
|
|
|
root_files = list_files_in_directory(args.data_dir) |
|
|
if not root_files: |
|
|
print("No ROOT files found in {}".format(args.data_dir)) |
|
|
return |
|
|
|
|
|
print("Inspecting all {} ROOT files in {}".format(len(root_files), args.data_dir)) |
|
|
print("=" * 80) |
|
|
|
|
|
for i, filepath in enumerate(root_files, 1): |
|
|
filename = os.path.basename(filepath) |
|
|
print("\n[{}/{}] Inspecting: {}".format(i, len(root_files), filename)) |
|
|
print("-" * 40) |
|
|
inspect_root_file(filepath, show_stats=not args.no_stats, max_entries=args.max_entries) |
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
if not args.filepath: |
|
|
|
|
|
root_files = list_files_in_directory(args.data_dir) |
|
|
if root_files: |
|
|
print("Available ROOT files in {}:".format(args.data_dir)) |
|
|
for i, filepath in enumerate(root_files, 1): |
|
|
filename = os.path.basename(filepath) |
|
|
print(" {}. {}".format(i, filename)) |
|
|
|
|
|
try: |
|
|
choice = input("\nEnter file number or full path (or 'q' to quit): ").strip() |
|
|
if choice.lower() == 'q': |
|
|
return |
|
|
if choice.isdigit(): |
|
|
idx = int(choice) - 1 |
|
|
if 0 <= idx < len(root_files): |
|
|
filepath = root_files[idx] |
|
|
else: |
|
|
print("Invalid choice!") |
|
|
return |
|
|
else: |
|
|
filepath = choice |
|
|
except KeyboardInterrupt: |
|
|
print("\nExiting...") |
|
|
return |
|
|
else: |
|
|
filepath = input("Enter path to ROOT file: ").strip() |
|
|
else: |
|
|
filepath = args.filepath |
|
|
|
|
|
|
|
|
if not os.path.isabs(filepath): |
|
|
filepath = os.path.join(args.data_dir, filepath) |
|
|
|
|
|
inspect_root_file(filepath, show_stats=not args.no_stats, max_entries=args.max_entries) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
main() |
|
|
|