Project: s41467-025-58227-1 | Function: _yield_calculate (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:** Calculates theoretical and actual yields for bio-based chemical production using genome-scale metabolic models (GEMs). Performs flux balance analysis (FBA) optimization to determine maximum product yields from different carbon sources under various aeration conditions, implementing the core metabolic engineering calculations described in the paper.

**KEY TERMS:** {
  "YT": "theoretical yield",
  "YA": "actual yield",
  "FBA": "flux balance analysis",
  "target_chemical": "bio-based chemical product"
}

**CONTEXT CODE:**         prev_coeff = model.reactions.r_4598.get_coefficient(met_id)
        model.reactions.r_4598.subtract_metabolites({model.metabolites.get_by_id(met_id): prev_coeff})
        
    for rxn_id in ['EX_ergst_e', 'EX_lanost_e', 'EX_hdcea_e', 'EX_zymst_e', 'r_2134', 'r_2137', 'EX_ocdcea_e']:
        model.reactions.get_by_id(rxn_id).lower_bound = -1000
        
    for rxn_id in ['MDHm', 'MDH']:
        model.reactions.get_by_id(rxn_id).lower_bound = 0
    for rxn_id in ['GLUSx']:
        model.reactions.get_by_id(rxn_id).upper_bound = 0
        
    return model



def _optimize_model(model, carbon_source, prev_lb, carbon_num, target_chem_id, achievable):
    with model as m:
        m.reactions.get_by_id(carbon_source).lower_bound = prev_lb * carbon_num / 6
        if achievable:
            max_bio = m.slim_optimize()
            if isnan(max_bio):
                return 0, 0
            elif abs(max_bio) < 1e-3:
                return 0, 0
            else:
                for rxn in m.reactions:
                    if rxn.objective_coefficient == 1:
                        biomass_rxn = rxn.id 
                m.reactions.get_by_id(biomass_rxn).lower_bound = max_bio*0.1
        else:
            m.reactions.ATPM.lower_bound = 0
        obj_reaction = 'EXT_%s_c'%target_chem_id
        m.objective = obj_reaction
        m.objective_direction = 'max'
        sol = m.optimize()

    if sol.status == 'infeasible':
        target_flux = 0
        carbon_flux = 0
    elif abs(sol.fluxes[carbon_source]) < 1e-3:
        target_flux = 0
        carbon_flux = 0
    else:
        target_flux = max(0, sol.fluxes[obj_reaction])
        carbon_flux = -sol.fluxes[carbon_source]
        
    return target_flux, carbon_flux



def _yield_calculate(target_models, model_name, carbon_source, carbon_num, prev_lb, achievable=False):
    """
    Calculates theoretical and actual yields for bio-based chemical production using genome-scale metabolic models (GEMs).

    This function performs flux balance analysis (FBA) optimization to determine maximum product yields
    from different carbon sources under various aeration conditions, implementing the core metabolic
    engineering calculations described in the paper for comprehensive evaluation of microbial cell
    factories.

    The method systematically evaluates 235 chemicals across five microorganisms using nine key
    carbon sources, calculating both theoretical yield (YT) and actual yield (YA) metrics that
    are fundamental for metabolic engineering applications.

    Args:
        target_models (dict): Dictionary of COBRA model objects for different target chemicals
        model_name (str): Base name pattern for model identification
        carbon_source (str): Carbon source reaction ID for flux balance analysis
        carbon_num (int): Number of carbon atoms in the carbon source
        prev_lb (float): Previous lower bound for carbon uptake rate
        achievable (bool): Whether to calculate achievable yields with biomass constraints

    Returns:
        tuple: (yield_table DataFrame, multi_paths list) containing calculated yields and pathway info

    Key algorithmic elements:
    - Flux balance analysis optimization
    - Metabolic flux calculation for yield determination
    - Yield computation across multiple carbon sources
    - Constraint handling for realistic biological conditions
    - Multi-pathway analysis for alternative biosynthetic routes

    Paper reference: "We calculated both YT and YA for 235 chemicals when produced in five
                    microorganisms using nine key carbon sources under different aeration conditions"
    Formula: Yield = (Product formation rate) / (Substrate consumption rate)

    Implementation details:
    - Processes genome-scale metabolic models for yield optimization
    - Handles both single-pathway and multi-pathway biosynthetic routes
    - Calculates molar, carbon-molar, and gram-based yield metrics
    - Provides comprehensive metabolic engineering assessment framework
    """
    # MASKED: Theoretical and actual yield calculation implementation for bio-based chemical production
    raise NotImplementedError("This function is masked for testing purposes. The function calculates theoretical and actual yields for bio-based chemical production using genome-scale metabolic models (GEMs), performing flux balance analysis (FBA) optimization to determine maximum product yields from different carbon sources under various aeration conditions, implementing the core metabolic engineering calculations described in the paper.")


def _multipath_yield_calculate(multi_paths, target_models, model_name, carbon_source, carbon_num, prev_lb, achievable=False):
    results = {}
    p_multi = re.compile('%s_(\w+)_path_(\d+).xml'%model_name)
    p = re.compile('%s_(\w+).xml'%model_name)
    with tqdm(len(multi_paths), position=0, leave=True) as pbar:
        for i, each_target in enumerate(tqdm(multi_paths, position=0, leave=True)):
            results_target = {}
            for each_model in target_models:
                
                p_compile = p_multi.match(each_model)
                if not p_compile:
                    target_chem_id = p.match(each_model).group(1)
                    target_num = 0
                else:
                    target_chem_id = p_compile.group(1)
                    target_num = p_compile.group(2)
                
                if each_target != target_chem_id:
                    continue

                model = target_models[each_model]
                    
                target_chem = model.metabolites.get_by_id(target_chem_id+'_c')
                target_chem_name = target_chem.name
                target_chem_MW = target_chem.formula_weight
                carbon_source_MW = model.metabolites.get_by_id(carbon_source[3:]).formula_weight
                
                target_flux, carbon_flux = _optimize_model(model, carbon_source, prev_lb, carbon_num, target_chem_id, achievable)

                if carbon_flux == 0:
                    molar_yield = 0
                else:
                    molar_yield = np.divide(target_flux, carbon_flux)
                molar_c_yield = molar_yield / carbon_num
                gram_yield = molar_yield * target_chem_MW / carbon_source_MW
                
                chem_yield = (target_chem_id, molar_yield, molar_c_yield, gram_yield)
                results_target[f'{target_chem_name}_path_{target_num}'] = chem_yield
                results_target_table = pd.DataFrame.from_dict(results_target).T
                results_target_table.columns = ['target ID', 'molar yield (mol/mol)', 'molar yield (mol/C mol)', 'gram yield (g/g)']
                results_target_table = results_target_table.round(6)
                results_target_table.sort_index()
            
            results[each_target] = results_target_table
            pbar.set_description('Model number %s\tTarget chemical: %s'%(i, target_chem_id))
        
    return results


def saveYieldCalculationResult(target_models, model_name, carbon_source, carbon_num, prev_lb, ngam, achievable=False):
    yield_table, multi_paths = _yield_calculate(target_models, model_name, carbon_source, carbon_num, prev_lb, achievable)
    multipath_yield_tables = _multipath_yield_calculate(multi_paths, target_models, model_name, carbon_source, carbon_num, prev_lb, achievable)
    multi_max_yield = {}
    for item in multipath_yield_tables:
        tmp_dir = './outputs/%s/multi_paths/%s'%(model_name, item)


Complete the function implementation replacing "raise NotImplementedError".