def compose_nncf_config(nncf_config: dict, enabled_options: list[str]) -> dict:
    """Compose NNCF config by selected options.

    This function merges different parts of the NNCF configuration based on enabled options.
    It supports ordered application of configuration parts through the ``order_of_parts`` field.

    Args:
        nncf_config (dict): Base NNCF configuration dictionary.
        enabled_options (list[str]): List of enabled optimization options.

    Returns:
        dict: Composed NNCF configuration.

    Raises:
        TypeError: If ``order_of_parts`` is not a list.
        ValueError: If an enabled option is not in ``order_of_parts``.
        KeyError: If ``base`` part or any enabled option is missing from config.
        RuntimeError: If there's an error during config merging.

    Example:
        >>> config = {
        ...     "base": {"epochs": 1},
        ...     "quantization": {"epochs": 2},
        ...     "order_of_parts": ["quantization"]
        ... }
        >>> result = compose_nncf_config(config, ["quantization"])
        >>> result["epochs"]
        2
    """
    optimisation_parts = nncf_config
    optimisation_parts_to_choose = []
    if "order_of_parts" in optimisation_parts:
        # The result of applying the changes from optimisation parts
        # may depend on the order of applying the changes
        # (e.g. if for nncf_quantization it is sufficient to have `total_epochs=2`,
        #  but for sparsity it is required `total_epochs=50`)
        # So, user can define `order_of_parts` in the optimisation_config
        # to specify the order of applying the parts.
        order_of_parts = optimisation_parts["order_of_parts"]
        if not isinstance(order_of_parts, list):
            msg = 'The field "order_of_parts" in optimization config should be a list'
            raise TypeError(msg)

        for part in enabled_options:
            if part not in order_of_parts:
                msg = f"The part {part} is selected, but it is absent in order_of_parts={order_of_parts}"
                raise ValueError(msg)

        optimisation_parts_to_choose = [part for part in order_of_parts if part in enabled_options]

    if "base" not in optimisation_parts:
        msg = 'Error: the optimisation config does not contain the "base" part'
        raise KeyError(msg)
    nncf_config_part = optimisation_parts["base"]

    for part in optimisation_parts_to_choose:
        if part not in optimisation_parts:
            msg = f'Error: the optimisation config does not contain the part "{part}"'
            raise KeyError(msg)
        optimisation_part_dict = optimisation_parts[part]
        try:
            nncf_config_part = merge_dicts_and_lists_b_into_a(nncf_config_part, optimisation_part_dict)
        except AssertionError as cur_error:
            err_descr = (
                f"Error during merging the parts of nncf configs:\n"
                f"the current part={part}, "
                f"the order of merging parts into base is {optimisation_parts_to_choose}.\n"
                f"The error is:\n{cur_error}"
            )
            raise RuntimeError(err_descr) from None

    return nncf_config_part
Compose NNCF config by selected options.

    This function merges different parts of the NNCF configuration based on enabled options.
    It supports ordered application of configuration parts through the ``order_of_parts`` field.

    Args:
        nncf_config (dict): Base NNCF configuration dictionary.
        enabled_options (list[str]): List of enabled optimization options.

    Returns:
        dict: Composed NNCF configuration.

    Raises:
        TypeError: If ``order_of_parts`` is not a list.
        ValueError: If an enabled option is not in ``order_of_parts``.
        KeyError: If ``base`` part or any enabled option is missing from config.
        RuntimeError: If there's an error during config merging.

    Example:
        >>> config = {
        ...     "base": {"epochs": 1},
        ...     "quantization": {"epochs": 2},
        ...     "order_of_parts": ["quantization"]
        ... }
        >>> result = compose_nncf_config(config, ["quantization"])
        >>> result["epochs"]
        2
    
src/anomalib/callbacks/nncf/utils.py