Utils Module

Contains general utility functions used throughout the HMB package.

HMB.Utils.ReadProjectConfig(configFilePath)[source]

Read the project configuration from the file. This function loads a configuration file in either YAML or JSON format and returns its contents as a dictionary.

Parameters:

configFilePath (str) – Path to the configuration file.

Returns:

Parsed configuration dictionary.

Return type:

dict

Raises:
  • ValueError – If the file format is not supported (not YAML or JSON).

  • AssertionError – If the configuration file does not exist.

Examples

import HMB.Utils as utils

config = utils.ReadProjectConfig("config.yaml")
print(config["projectName"])
HMB.Utils.IsPointInsideContour(point, contour)[source]

Check if a point is inside a contour.

\[\begin{split}\text{IsPointInsideContour}(point, contour) = \begin{cases} \text{True} & \text{if point is inside contour} \\ \text{False} & \text{otherwise} \end{cases}\end{split}\]

This function uses OpenCV’s pointPolygonTest to determine if a point is inside a given contour. It returns True if the point is inside the contour, otherwise it returns False.

Parameters:
  • point (tuple) – Coordinates of the point (x, y).

  • contour (numpy.ndarray) – Contour to check against the point. It should be a NumPy array of shape (n, 2), where n is the number of points in the contour and each point is represented by its (x, y) coordinates.

Returns:

True if the point is inside the contour, otherwise False.

Return type:

bool

HMB.Utils.IsIntersectingWithOtherContours(pointOrPolygon, contours)[source]

Check if a point intersects with any other contours.

\[\begin{split}\text{IsIntersectingWithOtherContours}(point, anListCoords) = \begin{cases} \text{True} & \text{if point intersects with any contour} \\ \text{False} & \text{otherwise} \end{cases}\end{split}\]

This function checks if a given point intersects with any contours defined by a list of coordinates. It iterates through each set of coordinates in the list and uses the IsPointInsideContour function to check for intersection. If the point is found to be inside any contour, it returns True; otherwise, it returns False.

Parameters:
  • point (tuple) – The point to check.

  • anListCoords (list) – List of coordinates of annotations. Each set of coordinates represents a contour where the first element is the x-coordinate and the second element is the y-coordinate.

Returns:

True if the point intersects with any contour, False otherwise.

Return type:

bool

HMB.Utils.WritePickleFile(filePath, data)[source]

Write data to a pickle file.

Parameters:
  • filePath (str) – Path to the pickle file.

  • data (Any) – Data to be written to the file.

HMB.Utils.ReadPickleFile(filePath)[source]

Read data from a pickle file.

Parameters:

filePath (str) – Path to the pickle file.

Returns:

The data read from the pickle file. Data type can be any Python object that was previously serialized and saved using pickle.

Return type:

object

Raises:

AssertionError – If the specified file does not exist.

HMB.Utils.WriteTextFile(filePath, text)[source]

Write text to a file.

Parameters:
  • filePath (str) – Path to the text file.

  • text (str) – Text to be written to the file.

HMB.Utils.ConvertToJsonSerializable(obj)[source]

Convert an object to a JSON-serializable format. This function attempts to convert various types of objects into formats that can be serialized to JSON. It handles common data types such as NumPy arrays, PyTorch tensors, TensorFlow tensors, bytes, and objects with __dict__ attributes. If an object cannot be converted to a JSON-serializable format, it falls back to using the string representation of the object. The function is designed to be robust and handle exceptions gracefully, ensuring that it can process a wide range of input types without crashing. It also includes structured representations for tensors to preserve data and metadata when possible, while providing fallback options when conversions fail. This makes it suitable for use in scenarios where you need to serialize complex objects to JSON, such as logging, configuration saving, or data interchange between systems that may include machine learning models and their parameters.

Parameters:

obj (Any) – The object to be converted to a JSON-serializable format.

Returns:

  • For NumPy arrays, it returns a dictionary containing the data as a list, shape, and data type.

  • For PyTorch tensors, it returns a dictionary with similar structure to preserve tensor information.

  • For TensorFlow tensors, it also returns a structured dictionary with data, shape, and data type.

  • For bytes and bytearrays, it attempts to decode them as UTF-8 strings, and if that fails, it returns their hexadecimal representation.

  • For objects with a __dict__ attribute, it returns a dictionary of their attributes, attempting to serialize each attribute directly or converting it to a string if it is not JSON-serializable.

  • For all other types of objects, it returns their string representation as a last resort. If the string conversion also fails, it returns None.

Return type:

A JSON-serializable representation of the input object. The return type can vary depending on the input

HMB.Utils.SimpleSerializeForJson(obj)[source]

Serialize an object into JSON-serializable primitives.

This function attempts to convert a variety of Python objects into structures that can be safely passed to json.dumps(). It performs a best-effort, recursive conversion for common types encountered in scientific and machine-learning workflows: - NumPy ndarrays -> nested lists - NumPy scalars -> native Python scalars - dict -> keys converted to strings and values serialized recursively - list/tuple -> serialized element-wise to a list - numeric types -> returned as-is - objects exposing a tolist() method -> converted via tolist() and serialized recursively

If an object cannot be converted via the above rules, the function falls back to using str(obj) for objects that expose tolist() but fail, or returns the object unchanged as a last resort.

Parameters:

obj (Any) – The object to convert to JSON-serializable form.

Returns:

A JSON-serializable representation of obj (nested dicts/lists/primitives), or the original object when no conversion was applicable.

Return type:

Any

HMB.Utils.DumpJsonFile(filePath, data, indent=2, ensureAscii=False)[source]

Dump data to a JSON file.

Parameters:
  • filePath (str) – Path to the JSON file.

  • data (object) – Data to be dumped to the JSON file.

  • indent (int, Optional) – Number of spaces for indentation in the JSON file. Default is 2.

  • ensureAscii (bool, Optional) – If True, all non-ASCII characters in the output are escaped. Default is False.

HMB.Utils.ReadJsonFile(filePath)[source]

Read data from a JSON file.

Parameters:

filePath (str) – Path to the JSON file.

Returns:

The data read from the JSON file as a Python object.

Return type:

object

Raises:

AssertionError – If the specified file does not exist.

HMB.Utils.ReadTextFile(filePath)[source]

Read text from a file.

Parameters:

filePath (str) – Path to the text file.

Returns:

The text read from the file.

Return type:

str

Raises:

AssertionError – If the specified file does not exist.

HMB.Utils.LoadYaml(yamlPath)[source]

Load data from a YAML file.

Parameters:

yamlPath (str) – Path to the YAML file.

Returns:

The data loaded from the YAML file as a Python object.

Return type:

object

Raises:

AssertionError – If the specified file does not exist.

HMB.Utils.SaveYaml(yamlPath, yamlData, safe=True)[source]

Save data to a YAML file.

Parameters:
  • yamlPath (str) – Path to the YAML file.

  • yamlData (object) – Data to be saved to the YAML file.

HMB.Utils.Hex2RGB(hexColor, isRGBA=False)[source]

Convert a hexadecimal color string to an RGB or RGBA tuple.

Parameters:
  • hexColor (str) – Hexadecimal color string (e.g., “#RRGGBB” or “RRGGBB”).

  • isRGBA (bool) – If True, return an RGBA tuple; otherwise, return an RGB tuple. Default is False.

Returns:

A tuple representing the RGB or RGBA color.

Return type:

tuple

import HMB.Utils as utils

rgbColor = utils.Hex2RGB("#FF5733")  # Returns (255, 87, 51).
rgbaColor = utils.Hex2RGB("#FF5733", isRGBA=True)  # Returns (255, 87, 51, 255).
print(f"RGB Color for #FF5733: {rgbColor}")
print(f"RGBA Color for #FF5733: {rgbaColor}")
HMB.Utils.AppendOrCreateNewCSV(fileName, data, header=None, mode='a')[source]

Append data to a CSV file or create a new one if it doesn’t exist.

Parameters:
  • fileName (str) – Path to the CSV file.

  • data (list or dict) – Data to append to the CSV file. Can be a list of rows (list of lists) or a dictionary.

  • header (list, Optional) – Header for the CSV file. Required if creating a new file.

  • mode (str, Optional) – Mode to open the file. Default is “a” (append). It can be changed to “w” (write) if needed.

HMB.Utils.AppendOrCreateNewDataFrameCSV(fileName, data, header=None)[source]

Append data to a CSV file or create a new one if it doesn’t exist. Accepts data as either a pandas DataFrame or a list (of lists or dictionaries).

Parameters:
  • fileName (str) – Path to the CSV file.

  • data (list or pandas.DataFrame) – Data to write. If list, must align with header.

  • header (list, Optional) – Column names. Required if creating a new file and data lacks column info.

HMB.Utils.GroupImagesByClass(inputDir, imgExtensions=None)[source]

Collect image paths grouped by class directory.

This implementation: - walks the input directory recursively once - accepts a wider set of image extensions (case-insensitive) - groups images by the top-level directory under inputDir (so nested subfolders such as augmentation folders don’t split a class into multiple keys) - sorts file lists deterministically and prints counts per class

Parameters:
  • inputDir (str) – Path to the input directory containing images.

  • imgExtensions (set, Optional) – Set of image file extensions to consider. Default includes common formats.

Returns:

A dictionary where keys are class names (top-level folder names) and values are lists of image file paths.

Return type:

dict

HMB.Utils.SelectBalancedImages(imageGroups, maxImages, seed=42)[source]

Select images evenly across classes up to maxImages. If there are not enough images, fill the remaining slots with random images from the available pool. The imageGroups parameter is a dictionary where keys are class names and values are lists of image file paths. You can obtain such a dictionary using the GroupImagesByClass function.

Parameters:
  • imageGroups (dict) – Dictionary where keys are class names and values are lists of image file paths.

  • maxImages (int) – Maximum number of images to select.

  • seed (int, Optional) – Random seed for reproducibility. Default is 42.

Returns:

List of selected image file paths.

Return type:

list

HMB.Utils.PrintHyperParamsList(hparamsFile, returnList=False)[source]

Print the list of hyperparameter sets from a hyperparameters file.

Parameters:
  • hparamsFile (str) – Path to the hyperparameters file.

  • returnList (bool, Optional) – If True, return the list of hyperparameter sets instead of printing. Default is False.

Returns:

If returnList is True, returns the list of hyperparameter sets; otherwise, returns None.

Return type:

list or None

HMB.Utils.FormatNumericWithDelta(value, baseValue=None, fmt='{:.2f}')[source]

Format a numeric value with its percentage delta relative to a baseline.

Parameters:
  • value (float or None) – The current value to format. If None, “N/A” will be returned.

  • baseValue (float or None) – The baseline value for comparison. If None or zero, the delta will not be computed to avoid division by zero.

  • fmt (str, Optional) – A format string for the value (default is “{:.2f}”). This should be a valid Python format string that can be used with the format method to format the value. For example, “{:.2f}” will format the value to two decimal places, while “{:.1f}” will format it to one decimal place. You can customize this format string based on your specific needs for displaying the value. The function will use this format string to format the value before appending the percentage delta in parentheses. If the value is missing (None), it will return “N/A” regardless of the format string. If the baseValue is missing or zero, it will return the formatted value without the delta to avoid division by zero errors.

Returns:

A formatted string that includes the value and its percentage delta relative to the baseline. The format of the returned string will be:
  • If value is None: “N/A”

  • If baseValue is None or zero: the formatted value without delta (e.g., “123.45”)

  • Otherwise: the formatted value followed by the percentage delta in parentheses (e.g., “123.45 (+10.0%)” or “123.45 (-5.0%)”).

Return type:

str

HMB.Utils.SafeCall(name, fn, *args, **kwargs)[source]

Safely call a function and print its result or any exceptions. It also prints a separator line for clarity.

Parameters:
  • name (str) – Name of the function being called (for reporting).

  • fn (Callable) – The function to call.

  • *args – Positional arguments to pass to the function.

  • **kwargs – Keyword arguments to pass to the function.

Returns:

The result of the function call if successful, or None if an exception occurred.

HMB.Utils.SafeTrapz(y, x=None)[source]

Robust trapezoidal integration wrapper.

Tries to use numpy.trapz when available. If NumPy is missing or the attribute is unavailable (some unusual environments), falls back to a pure-Python implementation that computes the trapezoidal rule over the provided samples.

Parameters:
  • y (Sequence) – y values (list/tuple/ndarray)

  • x (Sequence|None) – x coordinates. If None, samples are assumed to be equally spaced at integer positions 0..len(y)-1.

Returns:

Approximated integral value (area).

Return type:

float

HMB.Utils.SafeParseProbabilities(inputVar)[source]

Parse a probabilities object into a Python list of floats robustly.

Handling order (best-effort):
  • None -> [].

  • numeric scalar -> [float].

  • list/tuple/ndarray -> list of floats.

  • JSON string (e.g. “[0.1, 0.9]”).

  • Python literal string (e.g. “[0.1, 0.9]”).

  • strings containing NaN/nan -> handled (uses np.nan when numpy available).

Returns an empty list on unrecoverable parse errors.

Parameters:

inputVar (Any) – The input variable to parse as probabilities. This can be of various types, including None, numeric scalars, lists, tuples, numpy arrays, or strings representing lists of probabilities.

Returns:

A list of floats representing the parsed probabilities. If the input cannot be parsed, an empty list is returned. The function is designed to be robust and handle a wide range of input formats gracefully, making it suitable for parsing user input or configuration values that may be provided in different forms.

Return type:

list

HMB.Utils.CodeCarbonCodeEstimation(func)[source]

Estimate the carbon emissions of a function call using CodeCarbon. Reference: https://docs.codecarbon.io/latest/

You can also use:
  • codecarbon detect (to detect the hardware).

  • codecarbon monitor –no-api – python XXXX.py (To track any script without changing the code).

Parameters:

func (Callable) – The function to estimate emissions for. This should be a callable that can be executed without arguments.

Returns:

The estimated carbon emissions in kg CO2 equivalent, or None if estimation fails.

Return type:

float or None

HMB.Utils.fprint(msg, *args, **kwargs)[source]

Print a message with flush=True to ensure it appears immediately in the console.

Parameters:
  • msg (str) – The message to print.

  • *args – Additional positional arguments to pass to the print function.

  • **kwargs – Additional keyword arguments to pass to the print function.

class HMB.Utils.NumpyEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Bases: JSONEncoder

Custom JSON encoder for NumPy data types. This encoder extends the default JSONEncoder to handle NumPy arrays and scalars. It converts NumPy arrays to lists and NumPy scalars to native Python types (int or float) for JSON serialization.

Constructor for JSONEncoder, with sensible defaults.

If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, float or None. If skipkeys is True, such items are simply skipped.

If ensure_ascii is true, the output is guaranteed to be str objects with all incoming non-ASCII characters escaped. If ensure_ascii is false, the output can contain non-ASCII characters.

If check_circular is true, then lists, dicts, and custom encoded objects will be checked for circular references during encoding to prevent an infinite recursion (which would cause an RecursionError). Otherwise, no such check takes place.

If allow_nan is true, then NaN, Infinity, and -Infinity will be encoded as such. This behavior is not JSON specification compliant, but is consistent with most JavaScript based encoders and decoders. Otherwise, it will be a ValueError to encode such floats.

If sort_keys is true, then the output of dictionaries will be sorted by key; this is useful for regression tests to ensure that JSON serializations can be compared on a day-to-day basis.

If indent is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. None is the most compact representation.

If specified, separators should be an (item_separator, key_separator) tuple. The default is (’, ‘, ‘: ‘) if indent is None and (‘,’, ‘: ‘) otherwise. To get the most compact JSON representation, you should specify (‘,’, ‘:’) to eliminate whitespace.

If specified, default is a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError.

default(obj)[source]

Override the default method to handle NumPy data types.

Parameters:

obj (Any) – The object to serialize.

Returns:

A JSON-serializable representation of the object, or the result of the superclass’s default method for unsupported types.

Return type:

Any