File indexing completed on 2026-04-25 08:29:00
0001 """Shared utilities for EIC simulation campaign metadata scripts."""
0002
0003 import re
0004
0005 pwg_override_map = {
0006 "D0_ABCONV": "jets_hf",
0007 "Lc_ABCONV": "jets_hf",
0008 "DIJET_ABCONV": "jets_hf",
0009 "DIS": "inclusive",
0010 "SIDIS": "semi_inclusive",
0011 "EXCLUSIVE": "edt",
0012 }
0013
0014
0015 def detect_pwg(path):
0016 """Detect requester_pwg from a file path or DID path.
0017
0018 Returns:
0019 PWG string matching the schema enum, defaulting to 'other'.
0020 """
0021 for key, value in pwg_override_map.items():
0022 if f"/{key}/" in path or path.endswith(f"/{key}"):
0023 return value
0024 return "other"
0025
0026
0027 def detect_dsc(path, is_background_mixed=False):
0028 """Detect requester_dsc from a file path or DID path.
0029
0030 Args:
0031 path: File path or Rucio DID path string.
0032 is_background_mixed: True if the dataset includes background mixing.
0033
0034 Returns:
0035 DSC string if detected, or None.
0036 """
0037 if is_background_mixed or "Backgrounds" in path or "Bkg" in path or "BACKGROUNDS" in path:
0038 return "tracking"
0039 return None
0040
0041
0042 generators_list_ci = [
0043 "pythia6", "pythia8", "beagle", "djangoh", "rapgap", "dempgen",
0044 "sartre", "lager", "estarlight", "getalm", "eicmesonsfgen",
0045 "eic_sr_geant4", "eic_esr_xsuite", "sherpa",
0046 ]
0047
0048 generator_override_map = {
0049 "SYNRAD": "eic_sr_geant4",
0050 "DIS/NC": "pythia8",
0051 "DIS/CC": "pythia8",
0052 "UPSILON_ABCONV": "estarlight",
0053 }
0054
0055 _gen_pattern_ci = r'(' + '|'.join(generators_list_ci) + r')'
0056 _gen_pattern_epic = r'(EpIC)'
0057
0058
0059 def detect_q2(path):
0060 """Extract q2_min and q2_max from a file path or DID path.
0061
0062 Returns:
0063 Tuple (q2_min, q2_max) where either may be None if not found.
0064 """
0065 q2_min, q2_max = None, None
0066 range_match = re.search(r'q2_(\d+)(?:to|_)(\d+)', path, re.IGNORECASE)
0067 min_only_match = re.search(r'minQ2=(\d+)', path)
0068 q2_single_match = re.search(r'(?<![a-zA-Z])q2_(\d+)(?![to\d_])', path, re.IGNORECASE)
0069
0070 if range_match:
0071 q2_min, q2_max = int(range_match.group(1)), int(range_match.group(2))
0072 elif min_only_match:
0073 q2_min = int(min_only_match.group(1))
0074 elif q2_single_match:
0075 q2_min = int(q2_single_match.group(1))
0076
0077 return q2_min, q2_max
0078
0079
0080 def detect_generator(path, is_single=False):
0081 """Detect generator name from a file path or DID path.
0082
0083 Args:
0084 path: File path or Rucio DID path string.
0085 is_single: True if this is a single-particle run.
0086
0087 Returns:
0088 Generator name string matching the schema enum.
0089 """
0090 if is_single:
0091 return "single_particle"
0092 generator = "other"
0093 if re.search(_gen_pattern_epic, path):
0094 generator = "epic"
0095 else:
0096 m = re.search(_gen_pattern_ci, path, re.IGNORECASE)
0097 if m:
0098 generator = m.group(1).lower()
0099 for key, value in generator_override_map.items():
0100 if f"/{key}/" in path or path.endswith(f"/{key}"):
0101 generator = value
0102 break
0103 return generator