Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-10 09:18:03

0001 #!/usr/bin/env python3
0002 """Command-line interface for HepMC3 file normalization.
0003 
0004 This module can be invoked as:
0005     python -m acts.examples.hepmc3 [options]
0006 """
0007 
0008 import argparse
0009 import json
0010 import sys
0011 from pathlib import Path
0012 
0013 from . import (
0014     Compression,
0015     Format,
0016     availableCompressionModes,
0017     availableFormats,
0018     normalizeFiles,
0019 )
0020 
0021 
0022 def main(prog: str):
0023 
0024     parser = argparse.ArgumentParser(
0025         prog=prog,
0026         description="HepMC3 File Normalizer - Normalize and chunk HepMC files",
0027         formatter_class=argparse.RawDescriptionHelpFormatter,
0028         epilog="""
0029 Examples:
0030   # Multi-file mode with chunking
0031   %(prog)s -i input1.hepmc3.gz input2.hepmc3 -n 1000 -c zstd -l 9
0032   %(prog)s -i file.root -o normalized/ -p events -n 5000
0033 
0034   # Single output mode (format/compression auto-detected)
0035   %(prog)s -i input1.hepmc3.gz input2.hepmc3 -S combined.hepmc3.zst
0036   %(prog)s -i input.hepmc3.gz -S output/events.hepmc3.gz
0037         """,
0038     )
0039 
0040     parser.add_argument(
0041         "-i",
0042         "--input",
0043         nargs="+",
0044         required=True,
0045         metavar="FILE",
0046         help="Input HepMC files",
0047     )
0048 
0049     parser.add_argument(
0050         "-S",
0051         "--single-output",
0052         metavar="FILE",
0053         help="Write all events to a single output file. Format and compression are detected from filename.",
0054     )
0055 
0056     parser.add_argument(
0057         "-o",
0058         "--output-dir",
0059         default=".",
0060         metavar="DIR",
0061         help="Output directory (ignored with --single-output) [default: .]",
0062     )
0063 
0064     parser.add_argument(
0065         "-p",
0066         "--output-prefix",
0067         default="events",
0068         metavar="PREFIX",
0069         help="Output file prefix [default: events]",
0070     )
0071 
0072     parser.add_argument(
0073         "-n",
0074         "--events-per-file",
0075         type=int,
0076         default=10000,
0077         metavar="N",
0078         help="Number of events per output file (ignored with --single-output) [default: 10000]",
0079     )
0080 
0081     parser.add_argument(
0082         "-m",
0083         "--max-events",
0084         type=int,
0085         default=0,
0086         metavar="N",
0087         help="Maximum number of events to read (0 = all events) [default: 0]",
0088     )
0089 
0090     parser.add_argument(
0091         "-c",
0092         "--compression",
0093         choices=["none", "zlib", "lzma", "bzip2", "zstd"],
0094         default="none",
0095         help="Compression type (ignored with --single-output) [default: none]",
0096     )
0097 
0098     parser.add_argument(
0099         "-l",
0100         "--compression-level",
0101         type=int,
0102         default=6,
0103         metavar="LEVEL",
0104         help="Compression level (0-19, higher = more compression) [default: 6]",
0105     )
0106 
0107     parser.add_argument(
0108         "-f",
0109         "--format",
0110         choices=["ascii", "root"],
0111         default="ascii",
0112         help="Output format (ignored with --single-output) [default: ascii]",
0113     )
0114 
0115     parser.add_argument(
0116         "-j",
0117         "--json",
0118         action="store_true",
0119         help="Write JSON output with list of created files to stdout",
0120     )
0121 
0122     parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output")
0123 
0124     parser.add_argument(
0125         "--list-compressions",
0126         action="store_true",
0127         help="List available compression modes and exit",
0128     )
0129 
0130     args = parser.parse_args()
0131 
0132     # Handle --list-compressions
0133     if args.list_compressions:
0134         print("Available compression modes:")
0135         for comp in availableCompressionModes():
0136             print(f"  {comp}")
0137         print("\nAvailable formats:")
0138         for fmt in availableFormats():
0139             print(f"  {fmt}")
0140         return 0
0141 
0142     # Convert string compression to enum
0143     compression_map = {
0144         "none": Compression.none,
0145         "zlib": Compression.zlib,
0146         "lzma": Compression.lzma,
0147         "bzip2": Compression.bzip2,
0148         "zstd": Compression.zstd,
0149     }
0150 
0151     # Convert string format to enum
0152     format_map = {
0153         "ascii": Format.ascii,
0154         "root": Format.root,
0155     }
0156 
0157     try:
0158         # Convert inputs to Path objects
0159         input_files = [Path(f) for f in args.input]
0160         single_output = Path(args.single_output) if args.single_output else None
0161 
0162         # Run normalization
0163         result = normalizeFiles(
0164             inputFiles=input_files,
0165             singleOutputPath=single_output,
0166             outputDir=Path(args.output_dir),
0167             outputPrefix=args.output_prefix,
0168             eventsPerFile=args.events_per_file,
0169             maxEvents=args.max_events,
0170             format=format_map.get(args.format),
0171             compression=compression_map.get(args.compression),
0172             compressionLevel=args.compression_level,
0173             verbose=args.verbose,
0174         )
0175 
0176         # Write JSON output if requested
0177         if args.json:
0178             output = {
0179                 "num_events": result.numEvents,
0180                 "num_files": len(result.outputFiles),
0181                 "files": [
0182                     {
0183                         "path": str(Path(f).absolute()),
0184                         "size": Path(f).stat().st_size if Path(f).exists() else None,
0185                     }
0186                     for f in result.outputFiles
0187                 ],
0188             }
0189             print(json.dumps(output, indent=2))
0190 
0191         return 0
0192 
0193     except Exception as e:
0194         print(f"ERROR: {e}", file=sys.stderr)
0195         return 1
0196 
0197 
0198 if __name__ == "__main__":
0199     sys.exit(main(prog="acts.examples.hepmc3"))