Project: s41467-025-58227-1 | Function: predict_heterologous_reactions (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Predicts heterologous reactions that can improve yields of target chemicals in microbial production systems. Systematically evaluates candidate reactions from universal metabolic databases to identify engineering targets that enhance carbon efficiency and metabolic flux toward desired products.

**KEY TERMS:** {
  "heterologous_reactions": "non-native metabolic reactions",
  "universal_model": "comprehensive reaction database",
  "yield_improvement": "metabolic engineering enhancement",
  "phosphoketolase": "example heterologous enzyme"
}

**CONTEXT CODE:**     return add_reactions, remove_reactions


def set_model_condition(model, c_source, prev_c_source='glc__D', air='aerobic', maintenance=None):
    if air == 'aerobic':
        model.reactions.EX_o2_e.lower_bound = -1000
    elif air == 'anaerobic':
        if 'yeast' in model.id:
            model = _make_anaerobic_condition(model)
        model.reactions.EX_o2_e.lower_bound = 0
    elif air == 'microaerobic':
        if 'yeast' in model.id:
            model = _make_anaerobic_condition(model)
        model.reactions.EX_o2_e.lower_bound = -0.5
    else:
        raise Exception("Wrong air condition")
    
    c_source_rxn_id = f'EX_{c_source}_e'
    prev_c_source_rxn_id = f'EX_{prev_c_source}_e'

    p_C_num = re.compile('C(\d*)')

    c_source_chem = model.metabolites.get_by_id(c_source+'_e')
    prev_c_source_chem = model.metabolites.get_by_id(prev_c_source+'_e')

    c_source_C_num = p_C_num.match(c_source_chem.formula).group(1)
    if c_source_C_num == '':
        c_source_C_num = 1.0
    else:
        c_source_C_num = float(c_source_C_num)

    prev_c_source_C_num = p_C_num.match(prev_c_source_chem.formula).group(1)
    if prev_c_source_C_num == '':
        prev_c_source_C_num = 1.0
    else:
        prev_c_source_C_num = float(prev_c_source_C_num)

    carbon_ratio = c_source_C_num / prev_c_source_C_num

    prev_c_source_rxn = model.reactions.get_by_id(prev_c_source_rxn_id)
    prev_lb = prev_c_source_rxn.lower_bound
    prev_c_source_rxn.lower_bound = 0
    model.reactions.get_by_id(c_source_rxn_id).lower_bound = prev_lb / carbon_ratio

    if maintenance:
        model.reactions.get_by_id(maintenance).bounds = (0, 0)

    return model


def predict_heterologous_reactions(target_model, original_universal_model,
                                   c_source='EX_glc__D_e',
                                   limit_reaction_num=1, num_cpu=1,
                                   num_step=51):
    """
    Predicts heterologous reactions that can improve yields of target chemicals in microbial production systems.

    This function systematically evaluates candidate reactions from universal metabolic databases to
    identify engineering targets that enhance carbon efficiency and metabolic flux toward desired
    products. The method implements the core algorithm for identifying non-native metabolic reactions
    that can be introduced to improve biosynthetic pathway efficiency.

    The approach identifies heterologous enzymes (like phosphoketolase) that can create carbon- or
    energy-efficient biosynthetic pathways for target chemicals, enabling rational metabolic
    engineering design for enhanced microbial production systems.

    Args:
        target_model: COBRA model object representing the target organism with biosynthetic pathway
        original_universal_model: Comprehensive reaction database for candidate reaction screening
        c_source (str): Carbon source reaction ID for flux balance analysis
        limit_reaction_num (int): Maximum number of heterologous reactions to consider
        num_cpu (int): Number of CPU cores for parallel processing
        num_step (int): Number of optimization steps for yield improvement analysis

    Returns:
        bool or dict: False if no improvement found, or dictionary containing identified
                     heterologous reactions and their yield improvements

    Key algorithmic elements:
    - Reaction screening from universal metabolic databases
    - Yield optimization through gap-filling algorithms
    - Pathway analysis for metabolic flux enhancement
    - Database integration for comprehensive reaction coverage
    - Multi-step optimization for systematic improvement identification

    Paper reference: "The simulation identified candidate reactions that resulted in carbon- or
                    energy-efficient biosynthetic pathways for the chemicals. For example,
                    phosphoketolase, an enzyme that converts xylulose 5-phosphate"
    Formula: Heterologous reaction prediction for improved chemical yields

    Implementation details:
    - Integrates universal reaction databases with organism-specific models
    - Performs systematic gap-filling analysis for yield enhancement
    - Identifies optimal heterologous enzyme candidates
    - Evaluates carbon and energy efficiency improvements
    - Provides engineering targets for rational metabolic design
    """
    # MASKED: Heterologous reaction prediction implementation for yield improvement
    raise NotImplementedError("This function is masked for testing purposes. The function predicts heterologous reactions that can improve yields of target chemicals in microbial production systems, systematically evaluating candidate reactions from universal metabolic databases to identify engineering targets that enhance carbon efficiency and metabolic flux toward desired products.")

    with expanded_model as m:
        m.objective = target_reaction
        max_f = m.slim_optimize()
        if isnan(max_f) or abs(max_f) < 1e-3:
            max_f = 0
            return False
        m.reactions.get_by_id(target_reaction).bounds = (max_f, max_f)
        m.objective = c_source
        m.objective_direction = 'max'
        min_c = m.slim_optimize()

        if isnan(min_c) or abs(min_c) < 1e-3:
            min_c = 0
            logger.info('Unable to uptake carbon source in the expanded model')
            return False
        
    theoretical_yield = abs(max_f/min_c)
    if theoretical_yield - prev_theoretical_yield < 1e-3:
        logger.info('no yield improvement')
        return False
    elif theoretical_yield < 1e-3:
        logger.info('zero yield')
        return False
    
    logger.info('Improved max yield: %0.6f'%theoretical_yield)

    start_f = original_max_yield
    limit_f = original_max_yield * 1.5
    logger.info('From %s to %s'%(start_f, limit_f))
    yield_list = np.linspace(start_f, limit_f, num_step)
    target_identified = False
    identified_targets = []

    obj = GapFilling()
    obj.set_limit_number(limit_reaction_num)
    obj.set_cpu_number(num_cpu)
    obj.set_univ_model(universal_model)

    # for each_constraint in yield_list[1:]:
    for each_constraint in yield_list[::-1][:-1]:
        logger.info('Yield constraint : %0.3fX\t%0.6f'%(each_constraint/original_max_yield, each_constraint))
        obj.set_threshold(each_constraint)
        obj.set_additional_constr(identified_targets)
        result_info = obj.run_gap_filling(target_model, target_reaction)

        if len(result_info) == 0:
            # break
            continue
        for each_solution in result_info:
            target_reactions = result_info[each_solution]


Complete the function implementation replacing "raise NotImplementedError".