You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF 3.0方法导入Brightway后计算结果与Simapro不一致问题咨询

Brightway导入EF 3.0 LCIA方法计算结果与Simapro不一致问题

我编写了脚本将LCIA方法EF 3.0(调整版)的特征化因子导入Brightway,在Activity Browser中可查看到正确的特征化因子,但使用该方法执行计算时,得到的结果与导出CSV导入文件的Simapro计算结果不一致,其中气候变化方法计算结果甚至为0,单位看起来存在差异,但Brightway中其他可用方法也存在同样的单位差异情况。

此外我在其他相关问题中看到有计划实现EF 3.0方法的导入功能,请问该功能目前是否已可用?非常感谢各位的帮助。

导入脚本代码

import brightway2 as bw
import csv
import uuid
from bw2data import mapping
from bw2data.utils import recursive_str_to_unicode

class import_method_EF:
    '''Class for importing the EF method from Simapro export CSV file to Brightway. '''
    def __init__(
            self,
            project_name,
            name_file,
            ):
        self.project_name = project_name
        self.name_file = name_file
        self.db_biosphere = bw.Database('biosphere3')
        
        #Definition of the dictionnary for the correspondance between the Simapro and the ecoinvent categories
        self.dict_categories = {'high. pop.' : 'urban air close to ground',
                           'low. pop.' : 'low population density, long-term',
                           'river' : 'surface water',
                           'in water' : 'in water',
                           '(unspecified)' : '',
                           'ocean' : 'ocean',
                           'indoor' : 'indoor',
                           'stratosphere + troposphere' : 'lower stratosphere + upper troposphere',
                           'low. pop., long-term' : 'low population density, long-term',
                           'groundwater, long-term' : 'ground-, long-term',
                           'agricultural' : 'agricultural',
                           'industrial' : 'industrial',
                           }
        
        #Definition of the dictionnary of the ecoinvent units abreviations 
        self.dict_units = {'kg' : 'kilogram',
                            'kWh' : 'kilowatt hour',
                            'MJ' : 'megajoule',
                            'p':'p',
                            'unit':'unit',
                            'km':'kilometer',
                            'my' : 'meter-year',
                            'tkm' : 'ton kilometer',
                            'm3' : 'cubic meter',
                            'm2' :'square meter',
                            'kBq' : 'kilo Becquerel',
                            'm2a' : 'm2a', #à modifier
                            }
        
    def importation(self) :
        """
        Makes the importation from the Simapro CSV file to Brightway.
        """
        #Set the current project
        bw.projects.set_current(self.project_name)
        self.data = self.open_CSV(self.name_file, [])
        list_methods = []
        new_flows = []
        
        for i in range(len(self.data)) :
            if self.data[i] == ['Name'] :
                name_method = self.data[i+1][0]
            
            if self.data[i] == ['Impact category'] :
                list_flows = []
                j = 4
                while len(self.data[i+j])>1 :
                    biosphere_code = self.get_biosphere_code(self.data[i+j][2],self.data[i+j][1],self.data[i+j][0].lower())    
                    
                    if biosphere_code == 0 :
                        if self.find_if_already_new_flow(i+j, new_flows)[0] :
                            code = self.find_if_already_new_flow(i+j, new_flows)[1]
                            list_flows.append((('biosphere3', code),float(self.data[i+j][4].replace(',','.'))))
                        else :
                            code = str(uuid.uuid4())
                            while (self.db_biosphere.name, code) in mapping:
                                code = str(uuid.uuid4())
                                
                            new_flows.append({'amount' : float(self.data[i+j][4].replace(',','.')),
                                  'CAS number' : self.data[i+j][3],
                                  'categories' : (self.data[i+j][0].lower(), self.dict_categories[self.data[i+j][1]]),
                                  'name' : self.data[i+j][2],
                                  'unit' : self.dict_units[self.data[i+j][5]],
                                  'type' : 'biosphere',
                                  'code' : code})
                            list_flows.append((('biosphere3', code),float(self.data[i+j][4].replace(',','.'))))
                    else :
                        list_flows.append((('biosphere3', biosphere_code),float(self.data[i+j][4].replace(',','.'))))
                    j+=1
                list_methods.append({'name' : self.data[i+1][0],
                                     'unit' : self.data[i+1][1],
                                     'flows' : list_flows})
            
        new_flows = recursive_str_to_unicode(dict([self._format_flow(flow) for flow in new_flows]))
        if new_flows :
            print('new flows :',len(new_flows))
            self.new_flows = new_flows
            biosphere = bw.Database(self.db_biosphere.name)
            biosphere_data = biosphere.load()
            biosphere_data.update(new_flows)
            biosphere.write(biosphere_data)
            print('biosphere_data :',len(biosphere_data))
            
        for i in range(len(list_methods)) :
            method = bw.Method((name_method,list_methods[i]['name']))
            method.register(**{'unit':list_methods[i]['unit'],
                            'description':''})
            method.write(list_methods[i]['flows'])
            print(method.metadata)
            method.load()
        
    def open_CSV(self, CSV_file_name, list_rows):
        '''
        Opens a CSV file and gets a list of the rows.
        
        : param : CSV_file_name = str, name of the CSV file (must be in the working directory)
        : param : list_rows = list, list to get the rows
        
        : return : list_rows = list, list of the rows
        '''
        #Open the CSV file and read it
        with open(CSV_file_name, 'rt') as csvfile:
            data = csv.reader(csvfile, delimiter = ';')
            #Write every row in the list 
            for row in data:
                list_rows.append(row)
        return list_rows

    def get_biosphere_code(self, simapro_name, simapro_cat, type_biosphere):
        """
        Gets the Brightway code of a biosphere process given in a Simapro format.
        
        : param : simapro_name = str, name of the biosphere process in a Simapro format.
        : param : simapro_cat = str, category of the biosphere process (ex : high. pop., river, etc)
        : param : type_biosphere = str, type of the biosphere process (ex : Emissions to water, etc)
        
        : return :  0 if the process is not found in biosphere, the code otherwise
        """
        if 'GLO' in simapro_name or 'RER' in simapro_name :
            simapro_name = simapro_name[:-5]
        if '/m3' in simapro_name :
            simapro_name = simapro_name[:-3]
        
        #Search in the biosphere database, depending on the category
        if simapro_cat == '' :
            act_biosphere = self.db_biosphere.search(simapro_name, filter={'categories' : (type_biosphere,)})
        else :
            act_biosphere = self.db_biosphere.search(simapro_name, filter={'categories' : (type_biosphere, self.dict_categories[simapro_cat])})
        
        for act in act_biosphere :
            if simapro_cat == '' :
                if act['categories'] == (type_biosphere, ):
                    return act['code']
            else :
                if act['categories'] == (type_biosphere, self.dict_categories[simapro_cat]):
                    return act['code']
        return 0

    def _format_flow(self, cf):
        return (self.db_biosphere.name, cf['code']), {
            'exchanges': [],
            'categories': cf['categories'],
            'name': cf['name'],
            'type': ("resource" if cf["categories"][0] == "resource"
                     else "emission"),
            'unit': cf['unit'],
        }

    def find_if_already_new_flow(self, n, new_flows) :
        for k in range(len(new_flows)) :
            if new_flows[k]['name'] == self.data[n][2] :
                return True, new_flows[k]['code'] 
        return False, 0

问题排查补充

我已对get_biosphere_code方法进行修改,匹配效果有所优化(此前部分生物圈流无法被匹配到),但Brightway计算结果仍与Simapro存在较大差异,经排查发现两点问题:

  • ecoinvent活动尤其是生物圈流列表存在差异,与Simapro中的数据相比,Brightway及导入所用的ecoSpold数据中缺失部分流,这是结果差异的原因之一;
  • 两者LCA计算针对子类别的处理逻辑不同:例如气候变化方法的特征化因子列表中包含生物圈流“Carbon dioxide, fossil (air,)”,Simapro的LCA结果清单显示,所有排放到空气的化石源二氧化碳流均会被计入气候变化影响,不区分子类别;但Brightway仅会匹配完全一致的流,这也导致了较大的结果差异。

恳请各位帮忙分析问题原因,提供解决方案,谢谢。


内容的提问来源于stack exchange,提问作者pinarda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 01:36:03