Skip to content

helpers

Functions:

  • camel_to_snake

    Converts CamelCase to snake_case.

  • flatten_dict

    Recursively flattens a nested dictionary using a separator for keys.

  • format_time

    Formats elapsed time in seconds to a string in hh:mm:ss format.

  • parse_numbers

    Parses a mix of single numbers and ranges (e.g., '1,3:5,7' → [1, 3, 4, 5, 7])

  • unflatten_dict

    Rebuilds a deeply nested dictionary from flattened keys.

camel_to_snake

camel_to_snake(name: str) -> str

Converts CamelCase to snake_case.

Parameters:

  • name

    (str) –

    The CamelCase string to convert

Returns:

  • str

    The converted snake_case string

Source code in src/fpga_profile_reco/utils/helpers.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
def camel_to_snake(name: str) -> str: 
    """
    Converts CamelCase to snake_case.

    Parameters
    ----------
    name : str
        The CamelCase string to convert
    Returns
    -------
    str
        The converted snake_case string
    """
    s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
    return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()

flatten_dict

flatten_dict(d: dict, parent_key: str = '', sep='/') -> dict

Recursively flattens a nested dictionary using a separator for keys. Used to make it suitable to be saved as npz files.

Parameters:

  • d

    (dict) –

    The dictionary to flatten

  • parent_key

    (str, default: '' ) –

    The parent key to be used in the flattened dictionary

  • sep

    (str, default: '/' ) –

    The separator to be used between keys

Returns:

  • items ( dict ) –

    The flattened dictionary

Source code in src/fpga_profile_reco/utils/helpers.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def flatten_dict(d: dict, parent_key: str = '', sep='/') -> dict:
    """
    Recursively flattens a nested dictionary using a separator for keys.
    Used to make it suitable to be saved as npz files.

    Parameters
    ----------
    d : dict
        The dictionary to flatten
    parent_key : str
        The parent key to be used in the flattened dictionary
    sep : str
        The separator to be used between keys

    Returns
    -------
    items : dict
        The flattened dictionary
    """
    items = {}
    for k, v in d.items():
        new_key = f"{parent_key}{sep}{k}" if parent_key else k  # Maintain hierarchy in keys
        if isinstance(v, dict):  # Recursively flatten sub-dictionaries
            items.update(flatten_dict(v, new_key, sep=sep))
        else:
            items[new_key] = v  # Store floats or numpy arrays
    return items

format_time

format_time(elapsed: int | float) -> str

Formats elapsed time in seconds to a string in hh:mm:ss format.

Parameters:

  • elapsed

    (int or float) –

    The elapsed time in seconds to format

Returns:

  • str

    The formatted time string in hh:mm:ss format

Source code in src/fpga_profile_reco/utils/helpers.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def format_time(elapsed: int | float) -> str:
    """
    Formats elapsed time in seconds to a string in hh:mm:ss format.
    Parameters
    ----------
    elapsed : int or float
        The elapsed time in seconds to format

    Returns
    -------
    str
        The formatted time string in hh:mm:ss format
    """
    # Round to the nearest second.
    elapsed_rounded = round(elapsed)

    # Format as hh:mm:ss
    return str(datetime.timedelta(seconds=elapsed_rounded))

parse_numbers

parse_numbers(value: str) -> list[int]

Parses a mix of single numbers and ranges (e.g., '1,3:5,7' → [1, 3, 4, 5, 7])

Parameters:

  • value

    (str) –

    The string containing the numbers and ranges

Returns:

  • numbers ( list ) –

    The list of specified numbers

Source code in src/fpga_profile_reco/utils/helpers.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def parse_numbers(value: str) -> list[int]:
    """
    Parses a mix of single numbers and ranges (e.g., '1,3:5,7' → [1, 3, 4, 5, 7])

    Parameters
    ----------
    value : str
        The string containing the numbers and ranges

    Returns
    -------
    numbers : list
        The list of specified numbers
    """
    numbers = set()  # Use set to avoid duplicates
    parts = value.split(",")

    for part in parts:
        if ":" in part:  # Range detected (e.g., "3:5")
            try:
                start, end = map(int, part.split(":"))
                if start > end:
                    raise argparse.ArgumentTypeError(f"Invalid range '{part}': start must be <= end")
                numbers.update(range(start, end + 1))  # Expand range
            except ValueError:
                raise argparse.ArgumentTypeError(f"Invalid range format: '{part}' (use start:end)")
        else:  # Single number
            try:
                numbers.add(int(part))
            except ValueError:
                raise argparse.ArgumentTypeError(f"Invalid number: '{part}'")

    return sorted(numbers)  # Return sorted list

unflatten_dict

unflatten_dict(d: dict, sep='/') -> dict

Rebuilds a deeply nested dictionary from flattened keys. Used to restore the original structure of a dictionary saved as npz file.

Parameters:

  • d

    (dict) –

    The flattened dictionary

  • sep

    (str, default: '/' ) –

    The separator used between keys

Returns:

  • nested_dict ( dict ) –

    The nested dictionary

Source code in src/fpga_profile_reco/utils/helpers.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def unflatten_dict(d: dict, sep='/') -> dict:
    """
    Rebuilds a deeply nested dictionary from flattened keys.
    Used to restore the original structure of a dictionary saved as npz file.

    Parameters
    ----------
    d : dict
        The flattened dictionary
    sep : str
        The separator used between keys

    Returns
    -------
    nested_dict : dict
        The nested dictionary
    """
    nested_dict = {}
    for key, value in d.items():
        keys = key.split(sep)  # Split the composite key
        d_ref = nested_dict  # Reference to traverse/build dictionary

        for k in keys[:-1]:  # Traverse and create missing sub-dictionaries
            d_ref = d_ref.setdefault(k, {})

        d_ref[keys[-1]] = value  # Assign the final value

    return nested_dict