Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-08-31 08:24:38

0001 #!/usr/bin/env python3
0002 """
0003 make_mbdtrkz_lists.py <runnumber> [--nevents N] [--trkseg S] [--trkdst clus|tracks]
0004                       [--listdir DIR]
0005 
0006 Writes clus.list or tracks.list (controlled by --trkdst), and fit.list covering
0007 N events starting at block S (each block is N events).
0008 
0009   --nevents N          events per block (default 1000, must be a multiple of
0010                        EVT_PER_SEED=1000)
0011   --trkdst clus|tracks source DST type: 'clus' reads from dst_clus/<runnumber>.list
0012                        and writes clus.list; 'tracks' reads from dst_tracks/<runnumber>.list
0013                        and writes tracks.list (default: tracks)
0014   --listdir DIR        base directory containing dst_clus/, dst_tracks/, dst_fit/
0015                        (default: ~/sphenix/sphenix_bbc/run2025/lists/run3pp)
0016 
0017 Example:
0018   --nevents 100000 --trkdst clus    ->  clus segs   0-99,  fit seg 0
0019   --nevents 100000 --trkdst tracks  ->  tracks segs 100-199, fit seg 1
0020   --nevents 200000                  ->  tracks segs 200-399, fit segs 2-3
0021 
0022 Returns 0 on success, 1 if any expected DSTs are missing.
0023 """
0024 
0025 import os
0026 import re
0027 import sys
0028 
0029 EVT_PER_SEED =   1000   # events per track/clus/track DST file
0030 EVT_PER_FIT  = 100000   # events per fit DST file
0031 SEEDS_PER_FIT = EVT_PER_FIT // EVT_PER_SEED   # = 100
0032 
0033 
0034 def get_seg(filename):
0035     """Return the 5-digit trailing segment number from a DST filename, or None."""
0036     m = re.search(r'-(\d{5})\.root', filename)
0037     return int(m.group(1)) if m else None
0038 
0039 
0040 def lines_in_range(listfile, lo, hi):
0041     """Return stripped non-empty lines whose segment number is in [lo, hi]."""
0042     result = []
0043     with open(listfile) as fh:
0044         for line in fh:
0045             line = line.strip()
0046             if not line:
0047                 continue
0048             seg = get_seg(line)
0049             if seg is not None and lo <= seg <= hi:
0050                 result.append(line)
0051     return result
0052 
0053 
0054 def parse_args():
0055     args = sys.argv[1:]
0056     runnumber  = None
0057     nevents    = EVT_PER_FIT   # default: one fit-file block
0058     trkseg     = 0
0059     trkdst     = 'tracks'      # default DST type
0060     listdir    = os.path.expanduser('~/sphenix/sphenix_bbc/run2025/lists/run3pp')
0061     i = 0
0062     while i < len(args):
0063         if args[i] in ('--nevents', '-nevents'):
0064             if i + 1 >= len(args):
0065                 print('ERROR: --nevents requires an argument', file=sys.stderr)
0066                 sys.exit(1)
0067             nevents = int(args[i + 1])
0068             i += 2
0069         elif args[i] in ('--trkseg', '-trkseg'):
0070             if i + 1 >= len(args):
0071                 print('ERROR: --trkseg requires an argument', file=sys.stderr)
0072                 sys.exit(1)
0073             trkseg = int(args[i + 1])
0074             i += 2
0075         elif args[i] in ('--trkdst', '-trkdst'):
0076             if i + 1 >= len(args):
0077                 print('ERROR: --trkdst requires an argument', file=sys.stderr)
0078                 sys.exit(1)
0079             trkdst = args[i + 1]
0080             if trkdst not in ('clus', 'tracks'):
0081                 print(f'ERROR: --trkdst must be "clus" or "tracks", got "{trkdst}"',
0082                       file=sys.stderr)
0083                 sys.exit(1)
0084             i += 2
0085         elif args[i] in ('--listdir', '-listdir'):
0086             if i + 1 >= len(args):
0087                 print('ERROR: --listdir requires an argument', file=sys.stderr)
0088                 sys.exit(1)
0089             listdir = os.path.expanduser(args[i + 1])
0090             i += 2
0091         elif not args[i].startswith('-'):
0092             if runnumber is not None:
0093                 print('ERROR: unexpected argument', file=sys.stderr)
0094                 sys.exit(1)
0095             runnumber = int(args[i])
0096             i += 1
0097         else:
0098             print(f'ERROR: unknown option {args[i]}', file=sys.stderr)
0099             sys.exit(1)
0100 
0101     if runnumber is None:
0102         print(f'Usage: {sys.argv[0]} <runnumber> [--nevents N] [--trkseg S] [--trkdst clus|tracks] [--listdir DIR]',
0103               file=sys.stderr)
0104         sys.exit(1)
0105 
0106     if nevents <= 0 or nevents % EVT_PER_SEED != 0:
0107         print(f'ERROR: --nevents must be a positive multiple of {EVT_PER_SEED}',
0108               file=sys.stderr)
0109         sys.exit(1)
0110 
0111     return runnumber, nevents, trkseg, trkdst, listdir
0112 
0113 
0114 def main():
0115     runnumber, nevents, trkseg, trkdst, listdir = parse_args()
0116 
0117     tracks_per_block = nevents // EVT_PER_SEED
0118     fits_per_block  = (nevents + EVT_PER_FIT - 1) // EVT_PER_FIT  # ceiling div
0119 
0120     src_dir  = 'dst_clus' if trkdst == 'clus' else 'dst_tracks'
0121     out_name = 'clus.list' if trkdst == 'clus' else 'tracks.list'
0122 
0123     trk_list = os.path.join(listdir, src_dir, f'{runnumber}.list')
0124     fit_list = os.path.join(listdir, 'dst_fit', f'{runnumber}.list')
0125 
0126     for f in (trk_list, fit_list):
0127         if not os.path.isfile(f):
0128             print(f'ERROR: list file not found: {f}', file=sys.stderr)
0129             sys.exit(1)
0130 
0131     # segment starts
0132     trk_start = trkseg
0133     trk_end   = trk_start + tracks_per_block - 1
0134     fit_lo    = trk_start // SEEDS_PER_FIT
0135     fit_hi    = trk_end   // SEEDS_PER_FIT
0136 
0137     trk_lines = lines_in_range(trk_list, trk_start, trk_end)
0138     fit_lines = lines_in_range(fit_list, fit_lo,    fit_hi)
0139 
0140     trk_segs = len({get_seg(l) for l in trk_lines})
0141     fit_segs = len({get_seg(l) for l in fit_lines})
0142 
0143     rc = 0
0144     if trk_segs != tracks_per_block:
0145         print(f'ERROR: need {tracks_per_block} {trkdst} segments [{trk_start},{trk_end}], '
0146               f'found {trk_segs}', file=sys.stderr)
0147         rc = 1
0148     if fit_segs != fits_per_block:
0149         print(f'ERROR: need {fits_per_block} fit file(s) for segments [{fit_lo},{fit_hi}], '
0150               f'found {fit_segs}', file=sys.stderr)
0151         rc = 1
0152     if rc:
0153         sys.exit(1)
0154 
0155     with open(out_name, 'w') as f:
0156         f.write('\n'.join(trk_lines) + '\n')
0157     with open('fit.list', 'w') as f:
0158         f.write('\n'.join(fit_lines) + '\n')
0159 
0160     print(f'{out_name}: {len(trk_lines)} files ({trk_segs} unique segments)')
0161     print(f'fit.list:  {len(fit_lines)} files (segs {fit_lo}-{fit_hi})')
0162 
0163 
0164 if __name__ == '__main__':
0165     main()