ATLAS Offline Software
Loading...
Searching...
No Matches
FPGATrackSimHelperFunctions.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3
4import re
5
6def convertRegionsExpressionToArray(expression, min_value=0, max_value=1279):
7 if not expression or str(expression).strip() == "":
8 raise ValueError("No region expression provided.")
9
10 # Check if the expression is already a list or list-like string
11 if isinstance(expression, (list, tuple)):
12 result = [int(x) for x in expression if min_value <= int(x) <= max_value]
13 if not result:
14 raise ValueError("No valid regions after filtering by range.")
15 return result
16
17 # Check if it's a string representation of a list
18 if isinstance(expression, str):
19 expression_stripped = expression.strip()
20 if expression_stripped.startswith('[') and expression_stripped.endswith(']'):
21 try:
22 # Parse the list string
23 list_content = expression_stripped[1:-1].strip()
24 if list_content:
25 values = [int(x.strip()) for x in list_content.split(',')]
26 if all(min_value <= x <= max_value for x in values):
27 return values
28 else:
29 out_of_range = [x for x in values if x < min_value or x > max_value]
30 raise ValueError(f"Values out of range [{min_value}-{max_value}]: {out_of_range}")
31 else:
32 raise ValueError("Empty list provided.")
33 except ValueError:
34 raise ValueError(f"Invalid list format: {expression}")
35
36 # Check if the expression is a single integer
37 if str(expression).isdigit():
38 num = int(expression)
39 if min_value <= num <= max_value:
40 return [num] # Return the single integer as a list
41 else:
42 raise ValueError(f"Invalid choise: {expression}. Number out of range [{min_value}-{max_value}].")
43
44 # Start with all numbers within min_value to max_value
45 numbers = set(range(min_value, max_value + 1))
46
47 include_set = set()
48 exclude_set = set()
49
50 print(f"Initial expression: {str(expression)}")
51 if isinstance(expression, tuple) or isinstance(expression, list):
52 expression = ",".join(map(str, expression))
53
54 # Handle asterisk to return all values
55 if expression.strip() == "*":
56 return list(range(min_value, max_value + 1))
57
58 parts = expression.split(",") # Handle single-element expressions
59 print(f"Parts after split: {parts}")
60 for part in parts:
61 part = part.strip()
62
63
64 # Exclude regions (e.g. "!5-30")
65 if part.startswith("!"):
66 exclude_set.update(parse_range_or_wildcard(part[1:], min_value, max_value))
67 else:
68 include_set.update(parse_range_or_wildcard(part, min_value, max_value))
69
70 # Apply inclusion if non-empty; otherwise, use full range
71 result = include_set if include_set else numbers
72 result -= exclude_set # Remove exclusions
73
74 # Ensure final result stays within valid bounds
75 result = {num for num in result if min_value <= num <= max_value}
76
77 if not result:
78 raise ValueError(f"No valid regions after applying expression: {expression}")
79
80 return list(sorted(result)) # Always return a sorted list
81
82def parse_range_or_wildcard(expr, min_value, max_value):
83 # Check for range (e.g., "5-30")
84 if "-" in expr and "*" not in expr:
85 start, end = map(int, expr.split("-"))
86 start, end = max(min_value, start), min(max_value, end) # Apply min/max limits
87 return set(range(start, end + 1))
88
89 # Check for explicit number
90 if expr.isdigit():
91 num = int(expr)
92 return {num} if min_value <= num <= max_value else set() # Ignore if out of range
93
94 if "eta" in expr:
95 etanum = int(expr.replace("eta",""))
96 # the lowest bits at the 32 phi regions
97 return parse_range_or_wildcard(f"{32*etanum}-{32*(etanum+1)-1}",min_value, max_value)
98
99 # Handle wildcards
100 pattern = "^" + expr.replace("*", ".*") + "$"
101 regex = re.compile(pattern)
102
103 return {num for num in range(min_value, max_value + 1) if regex.match(str(num))}
104
105if __name__ == "__main__":
106 # Cases to validate
107 test_cases = [
108 ("5", [5]), # Single number
109 ("5-10", [5, 6, 7, 8, 9, 10]), # Range
110 ("!5-10", list(range(0, 5)) + list(range(11, 1280))), # Exclusion range
111 ("5,10,15", [5, 10, 15]), # Multiple numbers
112 ("5-10,!7", [5, 6, 8, 9, 10]), # Range with exclusion
113 ("*", list(range(1280))), # Wildcard for all
114 ("!5", list(range(0, 5)) + list(range(6, 1280))), # Exclude single number
115 ("5-10,!7-8", [5, 6, 9, 10]), # Range with exclusion range
116 ("1*", [num for num in range(1280) if re.match(r"^1.*$", str(num))]), # Wildcard pattern
117 ("!9*", [num for num in range(1280) if not re.match(r"^9.*$", str(num))]), # Exclude wildcard pattern
118 ("[5,6,8,10]", [5, 6, 8, 10]), # List format
119 ]
120
121 for expression, expected in test_cases:
122 try:
124 assert result == expected, f"Test failed for {expression}: {result} != {expected}"
125 except Exception as e:
126 print(f"Test failed for {expression}: {e}")
127 import sys
128 sys.exit(1)
void print(char *figname, TCanvas *c1)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
STL class.
STL class.
convertRegionsExpressionToArray(expression, min_value=0, max_value=1279)
parse_range_or_wildcard(expr, min_value, max_value)