关于print_recursive_calculation函数仅返回活动直接贡献的技术问询
print_recursive_calculation to Show Direct Contributions Only Great question! The original function you shared calculates the full lifecycle impact of each activity (including contributions from all its upstream supply chain activities), which is why it includes those "downstream" (actually upstream) contributions you want to exclude.
To get only the direct impact of each activity—i.e., the impact caused by its own direct biosphere emissions/resource use, not the impacts from activities it depends on—we need to adjust how we calculate the score for each activity. Here's how to do it:
Key Concept
Direct contributions come only from an activity's biosphere flows (like CO₂ emissions, water use, etc.). Technical flows (transactions with other activities) don't contribute directly—their impacts are part of the upstream lifecycle, which we want to exclude. So instead of running a full LCIA for each activity, we'll calculate the impact of just its biosphere exchanges.
Modified Function
def print_direct_contributions(activity, lcia_method, amount=1, level=0, max_level=3, cutoff=1e-2): # Initialize LCA object once to get characterization factors and total lifecycle score lca_obj = bc.LCA({activity: amount}, lcia_method) lca_obj.lci() lca_obj.lcia() total_score = lca_obj.score # Total lifecycle score of the top-level activity def calculate_direct_score(act, act_amount): direct_score = 0.0 # Iterate over all direct biosphere flows of the activity for exc in act.biosphere(): # Get the characterization factor for this biosphere flow in the target LCIA method cf = lca_obj.characterization_matrix[ lca_obj.biosphere_dict[exc.input.key], lca_obj.method_dict[lcia_method] ] # Calculate the impact of this flow: CF × flow amount × activity scaling amount direct_score += cf * exc['amount'] * act_amount return direct_score # Calculate direct impact for the current activity direct_score = calculate_direct_score(activity, amount) # Skip entries that fall below the cutoff threshold relative to total lifecycle score if abs(direct_score) <= abs(total_score * cutoff): return # Print formatted direct contribution details print("{}{:4.3f} ({:06.4f}): {:.70}".format( " " * level, direct_score / total_score, direct_score, str(activity) )) # Recurse to upstream technical activities (if within max depth limit) if level < max_level: for exc in activity.technosphere(): print_direct_contributions( activity=exc.input, lcia_method=lcia_method, amount=amount * exc['amount'], level=level + 1, max_level=max_level, cutoff=cutoff )
What Changed & Why
- Removed full LCIA recalculation: Instead of calling
redo_lciafor each upstream activity (which computes its full lifecycle impact), we now calculate the direct score by summing the impact of the activity's own biosphere flows. - Added
calculate_direct_scorehelper: This function looks up the characterization factor (CF) for each biosphere flow in the given LCIA method, multiplies it by the flow's amount and the activity's scaling factor, and sums these values to get the direct impact. - Kept recursive traversal: We still traverse upstream technical activities, but now each entry only shows its own direct contributions, not the impact from its upstream suppliers.
- Consistent cutoff logic: We still use the total lifecycle score of the top-level activity for cutoff checks, so we only show meaningful direct contributions relative to the overall impact.
Important Notes
- Ensure you've initialized Brightway and loaded your project/data before using this function.
- If a biosphere flow has no characterization factor in your chosen LCIA method, it won't contribute to the direct score.
- You could adjust the cutoff to use the sum of all direct scores instead of the total lifecycle score if you want to prioritize relative contributions among direct impacts only.
内容的提问来源于stack exchange,提问作者Stücke

