edges 1.0.0__py3-none-any.whl → 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of edges might be problematic. Click here for more details.
- edges/__init__.py +2 -1
- edges/data/GeoPolRisk_elementary flows_2024.json +877 -0
- edges/edgelcia.py +486 -326
- edges/flow_matching.py +114 -60
- edges/georesolver.py +5 -13
- edges/logging_config.py +41 -0
- edges/uncertainty.py +22 -2
- edges/utils.py +57 -7
- {edges-1.0.0.dist-info → edges-1.0.2.dist-info}/METADATA +1 -1
- {edges-1.0.0.dist-info → edges-1.0.2.dist-info}/RECORD +12 -10
- {edges-1.0.0.dist-info → edges-1.0.2.dist-info}/WHEEL +0 -0
- {edges-1.0.0.dist-info → edges-1.0.2.dist-info}/top_level.txt +0 -0
edges/edgelcia.py
CHANGED
|
@@ -6,7 +6,6 @@ LCIA class.
|
|
|
6
6
|
|
|
7
7
|
import math
|
|
8
8
|
from collections import defaultdict
|
|
9
|
-
import logging
|
|
10
9
|
import json
|
|
11
10
|
from typing import Optional
|
|
12
11
|
from pathlib import Path
|
|
@@ -47,9 +46,9 @@ from .georesolver import GeoResolver
|
|
|
47
46
|
from .uncertainty import sample_cf_distribution, make_distribution_key, get_rng_for_key
|
|
48
47
|
from .filesystem_constants import DATA_DIR
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
import logging
|
|
50
|
+
|
|
51
|
+
logger = logging.getLogger(__name__)
|
|
53
52
|
|
|
54
53
|
|
|
55
54
|
def add_cf_entry(
|
|
@@ -333,6 +332,8 @@ class EdgeLCIA:
|
|
|
333
332
|
# Accept both "parameters" and "scenarios" for flexibility
|
|
334
333
|
self.parameters = parameters or {}
|
|
335
334
|
|
|
335
|
+
self.logger = logging.getLogger(f"{__name__}.{self.__class__.__name__}")
|
|
336
|
+
|
|
336
337
|
self.scenario = scenario # New: store default scenario
|
|
337
338
|
self.scenario_length = validate_parameter_lengths(parameters=self.parameters)
|
|
338
339
|
self.use_distributions = use_distributions
|
|
@@ -340,9 +341,6 @@ class EdgeLCIA:
|
|
|
340
341
|
self.random_seed = random_seed if random_seed is not None else 42
|
|
341
342
|
self.random_state = np.random.default_rng(self.random_seed)
|
|
342
343
|
|
|
343
|
-
self.logger = logging.getLogger(f"{__name__}.{self.__class__.__name__}")
|
|
344
|
-
self.logger.setLevel(logging.INFO)
|
|
345
|
-
|
|
346
344
|
self.lca = bw2calc.LCA(demand=self.demand)
|
|
347
345
|
self._load_raw_lcia_data()
|
|
348
346
|
self.cfs_mapping = []
|
|
@@ -509,8 +507,10 @@ class EdgeLCIA:
|
|
|
509
507
|
for pos in cf["positions"]
|
|
510
508
|
}
|
|
511
509
|
|
|
512
|
-
|
|
513
|
-
|
|
510
|
+
logger.info(
|
|
511
|
+
"Processed edges: %d",
|
|
512
|
+
len(self.processed_biosphere_edges)
|
|
513
|
+
+ len(self.processed_technosphere_edges),
|
|
514
514
|
)
|
|
515
515
|
|
|
516
516
|
self.unprocessed_biosphere_edges = [
|
|
@@ -749,8 +749,10 @@ class EdgeLCIA:
|
|
|
749
749
|
Leaves near-misses due to 'location' for later geo steps.
|
|
750
750
|
"""
|
|
751
751
|
|
|
752
|
+
log = self.logger.getChild("map") # edges.edgelcia.EdgeLCIA.map
|
|
753
|
+
|
|
752
754
|
self._initialize_weights()
|
|
753
|
-
self._preprocess_lookups() #
|
|
755
|
+
self._preprocess_lookups() # populates lookups and prefix indexes
|
|
754
756
|
|
|
755
757
|
# ---- Build direction-specific bundles -----------------------------------
|
|
756
758
|
DIR_BIO = "biosphere-technosphere"
|
|
@@ -806,13 +808,57 @@ class EdgeLCIA:
|
|
|
806
808
|
self.reversed_supplier_lookup_tech,
|
|
807
809
|
)
|
|
808
810
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
+
# --- helpers for concise logging -----------------------------------------
|
|
812
|
+
def _short(d, limit=180):
|
|
813
|
+
try:
|
|
814
|
+
s = str(d)
|
|
815
|
+
except Exception:
|
|
816
|
+
s = repr(d)
|
|
817
|
+
return s if len(s) <= limit else s[: limit - 1] + "…"
|
|
818
|
+
|
|
819
|
+
def _count_none(x):
|
|
820
|
+
return 0 if x is None else (len(x) if hasattr(x, "__len__") else 1)
|
|
821
|
+
|
|
822
|
+
# High-level preamble
|
|
823
|
+
log.debug(
|
|
824
|
+
"START map_exchanges | biosphere_edges=%d | technosphere_edges=%d | CFs=%d | req_supplier=%s | req_consumer=%s",
|
|
825
|
+
len(self.biosphere_edges),
|
|
826
|
+
len(self.technosphere_edges),
|
|
827
|
+
len(self.raw_cfs_data),
|
|
828
|
+
sorted(self.required_supplier_fields),
|
|
829
|
+
sorted(self.required_consumer_fields),
|
|
830
|
+
)
|
|
831
|
+
log.debug(
|
|
832
|
+
"Lookups | supplier_bio=%d keys | supplier_tech=%d keys | consumer=%d keys",
|
|
833
|
+
len(self.supplier_lookup_bio),
|
|
834
|
+
len(self.supplier_lookup_tech),
|
|
835
|
+
len(self.consumer_lookup),
|
|
836
|
+
)
|
|
837
|
+
|
|
838
|
+
matched_positions_total = 0
|
|
839
|
+
allow_bio_added = 0
|
|
840
|
+
allow_tec_added = 0
|
|
811
841
|
|
|
812
842
|
# Bind hot locals (micro-optimization)
|
|
813
843
|
consumer_lookup = self.consumer_lookup
|
|
814
844
|
reversed_consumer_lookup = self.reversed_consumer_lookup
|
|
815
845
|
|
|
846
|
+
# ---- Precompute required field tuples (no 'classifications') once
|
|
847
|
+
req_sup_nc = getattr(self, "_req_sup_nc", None)
|
|
848
|
+
if req_sup_nc is None:
|
|
849
|
+
self._req_sup_nc = tuple(
|
|
850
|
+
sorted(
|
|
851
|
+
k for k in self.required_supplier_fields if k != "classifications"
|
|
852
|
+
)
|
|
853
|
+
)
|
|
854
|
+
self._req_con_nc = tuple(
|
|
855
|
+
sorted(
|
|
856
|
+
k for k in self.required_consumer_fields if k != "classifications"
|
|
857
|
+
)
|
|
858
|
+
)
|
|
859
|
+
req_sup_nc = self._req_sup_nc
|
|
860
|
+
req_con_nc = self._req_con_nc
|
|
861
|
+
|
|
816
862
|
# Iterate CFs
|
|
817
863
|
for i, cf in enumerate(tqdm(self.raw_cfs_data, desc="Mapping exchanges")):
|
|
818
864
|
s_crit = cf["supplier"]
|
|
@@ -825,18 +871,16 @@ class EdgeLCIA:
|
|
|
825
871
|
|
|
826
872
|
if not rem:
|
|
827
873
|
# This direction already fully characterized
|
|
874
|
+
log.debug("CF[%d] dir=%s skipped: no remaining edges.", i, dir_name)
|
|
828
875
|
continue
|
|
829
876
|
|
|
830
|
-
# ---------- SUPPLIER side ----------
|
|
831
|
-
# Classifications prefilter (only across current adjacency keys)
|
|
832
877
|
# ---------- SUPPLIER side ----------
|
|
833
878
|
if "classifications" in s_crit:
|
|
834
|
-
# prefix-indexed fetch; intersect with current adjacency supplier keys
|
|
835
879
|
s_class_hits = _cls_candidates_from_cf(
|
|
836
880
|
s_crit["classifications"],
|
|
837
881
|
(
|
|
838
882
|
self.cls_prefidx_supplier_bio
|
|
839
|
-
if dir_name ==
|
|
883
|
+
if dir_name == DIR_BIO
|
|
840
884
|
else self.cls_prefidx_supplier_tech
|
|
841
885
|
),
|
|
842
886
|
adjacency_keys=set(ebs.keys()),
|
|
@@ -844,51 +888,28 @@ class EdgeLCIA:
|
|
|
844
888
|
else:
|
|
845
889
|
s_class_hits = None
|
|
846
890
|
|
|
847
|
-
# Non-class matches via cached index (location tested last internally)
|
|
848
891
|
cached_match_with_index.index = s_index
|
|
849
892
|
cached_match_with_index.lookup_mapping = s_lookup
|
|
850
893
|
cached_match_with_index.reversed_lookup = s_reversed
|
|
851
894
|
|
|
852
|
-
# ---- Precompute required field tuples (no 'classifications')
|
|
853
|
-
req_sup_nc = getattr(self, "_req_sup_nc", None)
|
|
854
|
-
if req_sup_nc is None:
|
|
855
|
-
self._req_sup_nc = tuple(
|
|
856
|
-
sorted(
|
|
857
|
-
k
|
|
858
|
-
for k in self.required_supplier_fields
|
|
859
|
-
if k != "classifications"
|
|
860
|
-
)
|
|
861
|
-
)
|
|
862
|
-
self._req_con_nc = tuple(
|
|
863
|
-
sorted(
|
|
864
|
-
k
|
|
865
|
-
for k in self.required_consumer_fields
|
|
866
|
-
if k != "classifications"
|
|
867
|
-
)
|
|
868
|
-
)
|
|
869
|
-
req_sup_nc = self._req_sup_nc
|
|
870
|
-
req_con_nc = self._req_con_nc
|
|
871
|
-
|
|
872
895
|
s_nonclass = {k: v for k, v in s_crit.items() if k != "classifications"}
|
|
873
896
|
s_out = cached_match_with_index(make_hashable(s_nonclass), req_sup_nc)
|
|
874
897
|
|
|
875
|
-
|
|
876
|
-
s_cands = s_out.matches
|
|
898
|
+
s_matches_raw = list(s_out.matches) # before adjacency & class refinement
|
|
877
899
|
if s_class_hits is not None:
|
|
878
|
-
s_cands = list(set(
|
|
879
|
-
|
|
900
|
+
s_cands = list(set(s_out.matches) & set(s_class_hits))
|
|
901
|
+
else:
|
|
902
|
+
s_cands = list(s_out.matches)
|
|
903
|
+
# must still have consumers in adjacency
|
|
904
|
+
s_cands = [s for s in s_cands if s in ebs]
|
|
880
905
|
|
|
881
|
-
# near-miss on location only (also filtered by classifications if present)
|
|
882
906
|
s_loc_only = set(s_out.location_only_rejects)
|
|
883
907
|
if s_class_hits is not None:
|
|
884
908
|
s_loc_only &= set(s_class_hits)
|
|
885
|
-
|
|
886
909
|
s_loc_required = ("location" in s_crit) and (
|
|
887
910
|
s_crit.get("location") is not None
|
|
888
911
|
)
|
|
889
912
|
|
|
890
|
-
# ---------- CONSUMER side ----------
|
|
891
|
-
# Classifications prefilter (use current direction’s consumer adjacency keys)
|
|
892
913
|
# ---------- CONSUMER side ----------
|
|
893
914
|
if "classifications" in c_crit:
|
|
894
915
|
c_class_hits = _cls_candidates_from_cf(
|
|
@@ -906,28 +927,82 @@ class EdgeLCIA:
|
|
|
906
927
|
c_nonclass = {k: v for k, v in c_crit.items() if k != "classifications"}
|
|
907
928
|
c_out = cached_match_with_index(make_hashable(c_nonclass), req_con_nc)
|
|
908
929
|
|
|
909
|
-
|
|
930
|
+
c_matches_raw = list(c_out.matches)
|
|
910
931
|
if c_class_hits is not None:
|
|
911
|
-
c_cands = list(set(
|
|
912
|
-
|
|
932
|
+
c_cands = list(set(c_out.matches) & set(c_class_hits))
|
|
933
|
+
else:
|
|
934
|
+
c_cands = list(c_out.matches)
|
|
935
|
+
c_cands = [c for c in c_cands if c in ebc]
|
|
913
936
|
|
|
914
937
|
c_loc_only = set(c_out.location_only_rejects)
|
|
915
938
|
if c_class_hits is not None:
|
|
916
939
|
c_loc_only &= set(c_class_hits)
|
|
917
|
-
|
|
918
940
|
c_loc_required = ("location" in c_crit) and (
|
|
919
941
|
c_crit.get("location") is not None
|
|
920
942
|
)
|
|
921
943
|
|
|
944
|
+
# ---- DEBUG: explain empty candidate sets
|
|
945
|
+
if not s_cands:
|
|
946
|
+
reason = []
|
|
947
|
+
if not s_matches_raw:
|
|
948
|
+
reason.append("no-index-match")
|
|
949
|
+
else:
|
|
950
|
+
reason.append(f"raw-matches={len(s_matches_raw)}")
|
|
951
|
+
if s_class_hits is not None and not (
|
|
952
|
+
set(s_matches_raw) & set(s_class_hits)
|
|
953
|
+
):
|
|
954
|
+
reason.append("class-filtered-out")
|
|
955
|
+
if s_class_hits is None:
|
|
956
|
+
reason.append("no-class-filter")
|
|
957
|
+
# check adjacency pruning
|
|
958
|
+
pruned = [s for s in s_matches_raw if s not in ebs]
|
|
959
|
+
if pruned and len(pruned) == len(s_matches_raw):
|
|
960
|
+
reason.append("all-pruned-by-adjacency")
|
|
961
|
+
log.debug(
|
|
962
|
+
"CF[%d] dir=%s supplier candidates empty | reasons=%s | s_crit=%s | raw=%d class_hits=%s ebs_keys=%d",
|
|
963
|
+
i,
|
|
964
|
+
dir_name,
|
|
965
|
+
",".join(reason),
|
|
966
|
+
_short(s_crit),
|
|
967
|
+
len(s_matches_raw),
|
|
968
|
+
_count_none(s_class_hits),
|
|
969
|
+
len(ebs),
|
|
970
|
+
)
|
|
971
|
+
|
|
972
|
+
if not c_cands:
|
|
973
|
+
reason = []
|
|
974
|
+
if not c_matches_raw:
|
|
975
|
+
reason.append("no-index-match")
|
|
976
|
+
else:
|
|
977
|
+
reason.append(f"raw-matches={len(c_matches_raw)}")
|
|
978
|
+
if c_class_hits is not None and not (
|
|
979
|
+
set(c_matches_raw) & set(c_class_hits)
|
|
980
|
+
):
|
|
981
|
+
reason.append("class-filtered-out")
|
|
982
|
+
if c_class_hits is None:
|
|
983
|
+
reason.append("no-class-filter")
|
|
984
|
+
pruned = [c for c in c_matches_raw if c not in ebc]
|
|
985
|
+
if pruned and len(pruned) == len(c_matches_raw):
|
|
986
|
+
reason.append("all-pruned-by-adjacency")
|
|
987
|
+
log.debug(
|
|
988
|
+
"CF[%d] dir=%s consumer candidates empty | reasons=%s | c_crit=%s | raw=%d class_hits=%s ebc_keys=%d",
|
|
989
|
+
i,
|
|
990
|
+
dir_name,
|
|
991
|
+
",".join(reason),
|
|
992
|
+
_short(c_crit),
|
|
993
|
+
len(c_matches_raw),
|
|
994
|
+
_count_none(c_class_hits),
|
|
995
|
+
len(ebc),
|
|
996
|
+
)
|
|
997
|
+
|
|
922
998
|
# ---------- Combine full matches using adjacency intersections ----------
|
|
923
999
|
positions = []
|
|
924
1000
|
if s_cands and c_cands:
|
|
925
|
-
cset = set(c_cands)
|
|
1001
|
+
cset = set(c_cands)
|
|
926
1002
|
for s in s_cands:
|
|
927
1003
|
cs = ebs.get(s)
|
|
928
1004
|
if not cs:
|
|
929
1005
|
continue
|
|
930
|
-
# no generator, no rem check here – pruning below already guards it
|
|
931
1006
|
for c in cs:
|
|
932
1007
|
if c in cset:
|
|
933
1008
|
positions.append((s, c))
|
|
@@ -942,6 +1017,17 @@ class EdgeLCIA:
|
|
|
942
1017
|
value=cf["value"],
|
|
943
1018
|
uncertainty=cf.get("uncertainty"),
|
|
944
1019
|
)
|
|
1020
|
+
matched_positions_total += len(positions)
|
|
1021
|
+
log.debug(
|
|
1022
|
+
"CF[%d] dir=%s MATCH | positions=%d | s_cands=%d c_cands=%d | s_loc_only=%d c_loc_only=%d",
|
|
1023
|
+
i,
|
|
1024
|
+
dir_name,
|
|
1025
|
+
len(positions),
|
|
1026
|
+
len(s_cands),
|
|
1027
|
+
len(c_cands),
|
|
1028
|
+
len(s_loc_only),
|
|
1029
|
+
len(c_loc_only),
|
|
1030
|
+
)
|
|
945
1031
|
|
|
946
1032
|
# prune matched edges from this direction
|
|
947
1033
|
for s, c in positions:
|
|
@@ -953,12 +1039,24 @@ class EdgeLCIA:
|
|
|
953
1039
|
ebc[c].discard(s)
|
|
954
1040
|
if not ebc[c]:
|
|
955
1041
|
del ebc[c]
|
|
1042
|
+
else:
|
|
1043
|
+
log.debug(
|
|
1044
|
+
"CF[%d] dir=%s NO-MATCH | s_cands=%d c_cands=%d | s_loc_only=%d c_loc_only=%d | rem=%d",
|
|
1045
|
+
i,
|
|
1046
|
+
dir_name,
|
|
1047
|
+
len(s_cands),
|
|
1048
|
+
len(c_cands),
|
|
1049
|
+
len(s_loc_only),
|
|
1050
|
+
len(c_loc_only),
|
|
1051
|
+
len(rem),
|
|
1052
|
+
)
|
|
956
1053
|
|
|
957
1054
|
# ---------- Build near-miss allowlists (location-only) ----------
|
|
958
1055
|
# supplier near-miss with consumer full matches
|
|
959
1056
|
if s_loc_required and s_loc_only and c_cands:
|
|
960
1057
|
cset = set(c_cands)
|
|
961
1058
|
bucket = allow_bio if dir_name == DIR_BIO else allow_tec
|
|
1059
|
+
added = 0
|
|
962
1060
|
for s in s_loc_only:
|
|
963
1061
|
cs = ebs.get(s)
|
|
964
1062
|
if not cs:
|
|
@@ -968,11 +1066,24 @@ class EdgeLCIA:
|
|
|
968
1066
|
for c in hit:
|
|
969
1067
|
if (s, c) in rem:
|
|
970
1068
|
bucket.add((s, c))
|
|
1069
|
+
added += 1
|
|
1070
|
+
if added:
|
|
1071
|
+
if dir_name == DIR_BIO:
|
|
1072
|
+
allow_bio_added += added
|
|
1073
|
+
else:
|
|
1074
|
+
allow_tec_added += added
|
|
1075
|
+
log.debug(
|
|
1076
|
+
"CF[%d] dir=%s allowlist add (supplier loc-only) | added=%d",
|
|
1077
|
+
i,
|
|
1078
|
+
dir_name,
|
|
1079
|
+
added,
|
|
1080
|
+
)
|
|
971
1081
|
|
|
972
1082
|
# consumer near-miss with supplier full matches
|
|
973
1083
|
if c_loc_required and c_loc_only and s_cands:
|
|
974
1084
|
sset = set(s_cands)
|
|
975
1085
|
bucket = allow_bio if dir_name == DIR_BIO else allow_tec
|
|
1086
|
+
added = 0
|
|
976
1087
|
for c in c_loc_only:
|
|
977
1088
|
ss = ebc.get(c)
|
|
978
1089
|
if not ss:
|
|
@@ -982,11 +1093,24 @@ class EdgeLCIA:
|
|
|
982
1093
|
for s in hit:
|
|
983
1094
|
if (s, c) in rem:
|
|
984
1095
|
bucket.add((s, c))
|
|
1096
|
+
added += 1
|
|
1097
|
+
if added:
|
|
1098
|
+
if dir_name == DIR_BIO:
|
|
1099
|
+
allow_bio_added += added
|
|
1100
|
+
else:
|
|
1101
|
+
allow_tec_added += added
|
|
1102
|
+
log.debug(
|
|
1103
|
+
"CF[%d] dir=%s allowlist add (consumer loc-only) | added=%d",
|
|
1104
|
+
i,
|
|
1105
|
+
dir_name,
|
|
1106
|
+
added,
|
|
1107
|
+
)
|
|
985
1108
|
|
|
986
1109
|
# both sides near-miss (rare but useful)
|
|
987
1110
|
if s_loc_required and c_loc_required and s_loc_only and c_loc_only:
|
|
988
1111
|
cset = set(c_loc_only)
|
|
989
1112
|
bucket = allow_bio if dir_name == DIR_BIO else allow_tec
|
|
1113
|
+
added = 0
|
|
990
1114
|
for s in s_loc_only:
|
|
991
1115
|
cs = ebs.get(s)
|
|
992
1116
|
if not cs:
|
|
@@ -996,6 +1120,18 @@ class EdgeLCIA:
|
|
|
996
1120
|
for c in hit:
|
|
997
1121
|
if (s, c) in rem:
|
|
998
1122
|
bucket.add((s, c))
|
|
1123
|
+
added += 1
|
|
1124
|
+
if added:
|
|
1125
|
+
if dir_name == DIR_BIO:
|
|
1126
|
+
allow_bio_added += added
|
|
1127
|
+
else:
|
|
1128
|
+
allow_tec_added += added
|
|
1129
|
+
log.debug(
|
|
1130
|
+
"CF[%d] dir=%s allowlist add (both loc-only) | added=%d",
|
|
1131
|
+
i,
|
|
1132
|
+
dir_name,
|
|
1133
|
+
added,
|
|
1134
|
+
)
|
|
999
1135
|
|
|
1000
1136
|
self._update_unprocessed_edges()
|
|
1001
1137
|
|
|
@@ -1003,6 +1139,17 @@ class EdgeLCIA:
|
|
|
1003
1139
|
self.eligible_edges_for_next_bio = allow_bio
|
|
1004
1140
|
self.eligible_edges_for_next_tech = allow_tec
|
|
1005
1141
|
|
|
1142
|
+
log.debug(
|
|
1143
|
+
"END map_exchanges | matched_positions=%d | allow_bio=%d | allow_tec=%d | processed_bio=%d | processed_tech=%d | unprocessed_bio=%d | unprocessed_tech=%d",
|
|
1144
|
+
matched_positions_total,
|
|
1145
|
+
len(allow_bio),
|
|
1146
|
+
len(allow_tec),
|
|
1147
|
+
len(self.processed_biosphere_edges),
|
|
1148
|
+
len(self.processed_technosphere_edges),
|
|
1149
|
+
len(self.unprocessed_biosphere_edges),
|
|
1150
|
+
len(self.unprocessed_technosphere_edges),
|
|
1151
|
+
)
|
|
1152
|
+
|
|
1006
1153
|
def map_aggregate_locations(self) -> None:
|
|
1007
1154
|
"""
|
|
1008
1155
|
Map unmatched exchanges using CFs from broader (aggregated) regions.
|
|
@@ -1034,7 +1181,7 @@ class EdgeLCIA:
|
|
|
1034
1181
|
"""
|
|
1035
1182
|
|
|
1036
1183
|
self._initialize_weights()
|
|
1037
|
-
|
|
1184
|
+
logger.info("Handling static regions…")
|
|
1038
1185
|
|
|
1039
1186
|
cf_operators = {
|
|
1040
1187
|
cf["supplier"].get("operator", "equals") for cf in self.raw_cfs_data
|
|
@@ -1181,47 +1328,48 @@ class EdgeLCIA:
|
|
|
1181
1328
|
)
|
|
1182
1329
|
|
|
1183
1330
|
# Pass 1
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1331
|
+
if len(prefiltered_groups) > 0:
|
|
1332
|
+
for sig, group_edges in tqdm(
|
|
1333
|
+
prefiltered_groups.items(), desc="Processing static groups (pass 1)"
|
|
1334
|
+
):
|
|
1335
|
+
supplier_info = group_edges[0][2]
|
|
1336
|
+
consumer_info = group_edges[0][3]
|
|
1337
|
+
candidate_supplier_locations = group_edges[0][-2]
|
|
1338
|
+
candidate_consumer_locations = group_edges[0][-1]
|
|
1339
|
+
|
|
1340
|
+
new_cf, matched_cf_obj, agg_uncertainty = compute_average_cf(
|
|
1341
|
+
candidate_suppliers=candidate_supplier_locations,
|
|
1342
|
+
candidate_consumers=candidate_consumer_locations,
|
|
1343
|
+
supplier_info=supplier_info,
|
|
1344
|
+
consumer_info=consumer_info,
|
|
1345
|
+
required_supplier_fields=self.required_supplier_fields,
|
|
1346
|
+
required_consumer_fields=self.required_consumer_fields,
|
|
1347
|
+
cf_index=self.cf_index,
|
|
1348
|
+
)
|
|
1201
1349
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1350
|
+
if new_cf != 0:
|
|
1351
|
+
for (
|
|
1352
|
+
supplier_idx,
|
|
1353
|
+
consumer_idx,
|
|
1354
|
+
supplier_info,
|
|
1355
|
+
consumer_info,
|
|
1356
|
+
_,
|
|
1357
|
+
_,
|
|
1358
|
+
) in group_edges:
|
|
1359
|
+
add_cf_entry(
|
|
1360
|
+
cfs_mapping=self.cfs_mapping,
|
|
1361
|
+
supplier_info=supplier_info,
|
|
1362
|
+
consumer_info=consumer_info,
|
|
1363
|
+
direction=direction,
|
|
1364
|
+
indices=[(supplier_idx, consumer_idx)],
|
|
1365
|
+
value=new_cf,
|
|
1366
|
+
uncertainty=agg_uncertainty,
|
|
1367
|
+
)
|
|
1368
|
+
else:
|
|
1369
|
+
self.logger.warning(
|
|
1370
|
+
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
1371
|
+
f"with candidate suppliers={candidate_supplier_locations} and consumers={candidate_consumer_locations}"
|
|
1219
1372
|
)
|
|
1220
|
-
else:
|
|
1221
|
-
self.logger.warning(
|
|
1222
|
-
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
1223
|
-
f"with candidate suppliers={candidate_supplier_locations} and consumers={candidate_consumer_locations}"
|
|
1224
|
-
)
|
|
1225
1373
|
|
|
1226
1374
|
# Pass 2
|
|
1227
1375
|
compute_cf_memoized = compute_cf_memoized_factory(
|
|
@@ -1237,33 +1385,34 @@ class EdgeLCIA:
|
|
|
1237
1385
|
required_consumer_fields=self.required_consumer_fields,
|
|
1238
1386
|
)
|
|
1239
1387
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1388
|
+
if len(grouped_edges) > 0:
|
|
1389
|
+
for (
|
|
1390
|
+
s_key,
|
|
1391
|
+
c_key,
|
|
1392
|
+
(candidate_suppliers, candidate_consumers),
|
|
1393
|
+
), edge_group in tqdm(
|
|
1394
|
+
grouped_edges.items(), desc="Processing static groups (pass 2)"
|
|
1395
|
+
):
|
|
1396
|
+
new_cf, matched_cf_obj, agg_uncertainty = compute_cf_memoized(
|
|
1397
|
+
s_key, c_key, candidate_suppliers, candidate_consumers
|
|
1398
|
+
)
|
|
1250
1399
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1400
|
+
if new_cf != 0:
|
|
1401
|
+
for supplier_idx, consumer_idx in edge_group:
|
|
1402
|
+
add_cf_entry(
|
|
1403
|
+
cfs_mapping=self.cfs_mapping,
|
|
1404
|
+
supplier_info=dict(s_key),
|
|
1405
|
+
consumer_info=dict(c_key),
|
|
1406
|
+
direction=direction,
|
|
1407
|
+
indices=[(supplier_idx, consumer_idx)],
|
|
1408
|
+
value=new_cf,
|
|
1409
|
+
uncertainty=agg_uncertainty,
|
|
1410
|
+
)
|
|
1411
|
+
else:
|
|
1412
|
+
self.logger.warning(
|
|
1413
|
+
f"Fallback CF could not be computed for supplier={s_key}, consumer={c_key} "
|
|
1414
|
+
f"with candidate suppliers={candidate_suppliers} and consumers={candidate_consumers}"
|
|
1261
1415
|
)
|
|
1262
|
-
else:
|
|
1263
|
-
self.logger.warning(
|
|
1264
|
-
f"Fallback CF could not be computed for supplier={s_key}, consumer={c_key} "
|
|
1265
|
-
f"with candidate suppliers={candidate_suppliers} and consumers={candidate_consumers}"
|
|
1266
|
-
)
|
|
1267
1416
|
|
|
1268
1417
|
self._update_unprocessed_edges()
|
|
1269
1418
|
|
|
@@ -1300,7 +1449,7 @@ class EdgeLCIA:
|
|
|
1300
1449
|
"""
|
|
1301
1450
|
|
|
1302
1451
|
self._initialize_weights()
|
|
1303
|
-
|
|
1452
|
+
logger.info("Handling dynamic regions…")
|
|
1304
1453
|
|
|
1305
1454
|
cf_operators = {
|
|
1306
1455
|
cf["supplier"].get("operator", "equals") for cf in self.raw_cfs_data
|
|
@@ -1450,47 +1599,49 @@ class EdgeLCIA:
|
|
|
1450
1599
|
)
|
|
1451
1600
|
|
|
1452
1601
|
# Pass 1
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1602
|
+
if len(prefiltered_groups) > 0:
|
|
1603
|
+
for sig, group_edges in tqdm(
|
|
1604
|
+
prefiltered_groups.items(),
|
|
1605
|
+
desc="Processing dynamic groups (pass 1)",
|
|
1606
|
+
):
|
|
1607
|
+
rep_supplier = group_edges[0][2]
|
|
1608
|
+
rep_consumer = group_edges[0][3]
|
|
1609
|
+
candidate_supplier_locations = group_edges[0][-2]
|
|
1610
|
+
candidate_consumer_locations = group_edges[0][-1]
|
|
1611
|
+
|
|
1612
|
+
new_cf, matched_cf_obj, agg_uncertainty = compute_average_cf(
|
|
1613
|
+
candidate_suppliers=candidate_supplier_locations,
|
|
1614
|
+
candidate_consumers=candidate_consumer_locations,
|
|
1615
|
+
supplier_info=rep_supplier,
|
|
1616
|
+
consumer_info=rep_consumer,
|
|
1617
|
+
required_supplier_fields=self.required_supplier_fields,
|
|
1618
|
+
required_consumer_fields=self.required_consumer_fields,
|
|
1619
|
+
cf_index=self.cf_index,
|
|
1620
|
+
)
|
|
1470
1621
|
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1622
|
+
if new_cf:
|
|
1623
|
+
for (
|
|
1624
|
+
supplier_idx,
|
|
1625
|
+
consumer_idx,
|
|
1626
|
+
supplier_info,
|
|
1627
|
+
consumer_info,
|
|
1628
|
+
_,
|
|
1629
|
+
_,
|
|
1630
|
+
) in group_edges:
|
|
1631
|
+
add_cf_entry(
|
|
1632
|
+
cfs_mapping=self.cfs_mapping,
|
|
1633
|
+
supplier_info=supplier_info,
|
|
1634
|
+
consumer_info=consumer_info,
|
|
1635
|
+
direction=direction,
|
|
1636
|
+
indices=[(supplier_idx, consumer_idx)],
|
|
1637
|
+
value=new_cf,
|
|
1638
|
+
uncertainty=agg_uncertainty,
|
|
1639
|
+
)
|
|
1640
|
+
else:
|
|
1641
|
+
self.logger.warning(
|
|
1642
|
+
f"Fallback CF could not be computed for supplier={rep_supplier}, consumer={rep_consumer} "
|
|
1643
|
+
f"with candidate suppliers={candidate_supplier_locations} and consumers={candidate_consumer_locations}"
|
|
1488
1644
|
)
|
|
1489
|
-
else:
|
|
1490
|
-
self.logger.warning(
|
|
1491
|
-
f"Fallback CF could not be computed for supplier={rep_supplier}, consumer={rep_consumer} "
|
|
1492
|
-
f"with candidate suppliers={candidate_supplier_locations} and consumers={candidate_consumer_locations}"
|
|
1493
|
-
)
|
|
1494
1645
|
|
|
1495
1646
|
# Pass 2
|
|
1496
1647
|
compute_cf_memoized = compute_cf_memoized_factory(
|
|
@@ -1506,36 +1657,37 @@ class EdgeLCIA:
|
|
|
1506
1657
|
required_consumer_fields=self.required_consumer_fields,
|
|
1507
1658
|
)
|
|
1508
1659
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
c_key,
|
|
1512
|
-
(candidate_supplier_locations, candidate_consumer_locations),
|
|
1513
|
-
), edge_group in tqdm(
|
|
1514
|
-
grouped_edges.items(), desc="Processing dynamic groups (pass 2)"
|
|
1515
|
-
):
|
|
1516
|
-
new_cf, matched_cf_obj, agg_uncertainty = compute_cf_memoized(
|
|
1660
|
+
if len(grouped_edges) > 0:
|
|
1661
|
+
for (
|
|
1517
1662
|
s_key,
|
|
1518
1663
|
c_key,
|
|
1519
|
-
candidate_supplier_locations,
|
|
1520
|
-
|
|
1521
|
-
|
|
1664
|
+
(candidate_supplier_locations, candidate_consumer_locations),
|
|
1665
|
+
), edge_group in tqdm(
|
|
1666
|
+
grouped_edges.items(), desc="Processing dynamic groups (pass 2)"
|
|
1667
|
+
):
|
|
1668
|
+
new_cf, matched_cf_obj, agg_uncertainty = compute_cf_memoized(
|
|
1669
|
+
s_key,
|
|
1670
|
+
c_key,
|
|
1671
|
+
candidate_supplier_locations,
|
|
1672
|
+
candidate_consumer_locations,
|
|
1673
|
+
)
|
|
1522
1674
|
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1675
|
+
if new_cf:
|
|
1676
|
+
for supplier_idx, consumer_idx in edge_group:
|
|
1677
|
+
add_cf_entry(
|
|
1678
|
+
cfs_mapping=self.cfs_mapping,
|
|
1679
|
+
supplier_info=dict(s_key),
|
|
1680
|
+
consumer_info=dict(c_key),
|
|
1681
|
+
direction=direction,
|
|
1682
|
+
indices=[(supplier_idx, consumer_idx)],
|
|
1683
|
+
value=new_cf,
|
|
1684
|
+
uncertainty=agg_uncertainty,
|
|
1685
|
+
)
|
|
1686
|
+
else:
|
|
1687
|
+
self.logger.warning(
|
|
1688
|
+
f"Fallback CF could not be computed for supplier={s_key}, consumer={c_key} "
|
|
1689
|
+
f"with candidate suppliers={candidate_supplier_locations} and consumers={candidate_consumer_locations}"
|
|
1533
1690
|
)
|
|
1534
|
-
else:
|
|
1535
|
-
self.logger.warning(
|
|
1536
|
-
f"Fallback CF could not be computed for supplier={s_key}, consumer={c_key} "
|
|
1537
|
-
f"with candidate suppliers={candidate_supplier_locations} and consumers={candidate_consumer_locations}"
|
|
1538
|
-
)
|
|
1539
1691
|
|
|
1540
1692
|
self._update_unprocessed_edges()
|
|
1541
1693
|
|
|
@@ -1568,7 +1720,7 @@ class EdgeLCIA:
|
|
|
1568
1720
|
"""
|
|
1569
1721
|
|
|
1570
1722
|
self._initialize_weights()
|
|
1571
|
-
|
|
1723
|
+
logger.info("Handling contained locations…")
|
|
1572
1724
|
|
|
1573
1725
|
cf_operators = {
|
|
1574
1726
|
cf["supplier"].get("operator", "equals") for cf in self.raw_cfs_data
|
|
@@ -1704,47 +1856,49 @@ class EdgeLCIA:
|
|
|
1704
1856
|
)
|
|
1705
1857
|
|
|
1706
1858
|
# Pass 1
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1859
|
+
if len(prefiltered_groups) > 0:
|
|
1860
|
+
for sig, group_edges in tqdm(
|
|
1861
|
+
prefiltered_groups.items(),
|
|
1862
|
+
desc="Processing contained groups (pass 1)",
|
|
1863
|
+
):
|
|
1864
|
+
supplier_info = group_edges[0][2]
|
|
1865
|
+
consumer_info = group_edges[0][3]
|
|
1866
|
+
candidate_supplier_locations = group_edges[0][-2]
|
|
1867
|
+
candidate_consumer_locations = group_edges[0][-1]
|
|
1868
|
+
|
|
1869
|
+
new_cf, matched_cf_obj, agg_uncertainty = compute_average_cf(
|
|
1870
|
+
candidate_suppliers=candidate_supplier_locations,
|
|
1871
|
+
candidate_consumers=candidate_consumer_locations,
|
|
1872
|
+
supplier_info=supplier_info,
|
|
1873
|
+
consumer_info=consumer_info,
|
|
1874
|
+
required_supplier_fields=self.required_supplier_fields,
|
|
1875
|
+
required_consumer_fields=self.required_consumer_fields,
|
|
1876
|
+
cf_index=self.cf_index,
|
|
1877
|
+
)
|
|
1724
1878
|
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1879
|
+
if new_cf:
|
|
1880
|
+
for (
|
|
1881
|
+
supplier_idx,
|
|
1882
|
+
consumer_idx,
|
|
1883
|
+
supplier_info,
|
|
1884
|
+
consumer_info,
|
|
1885
|
+
_,
|
|
1886
|
+
_,
|
|
1887
|
+
) in group_edges:
|
|
1888
|
+
add_cf_entry(
|
|
1889
|
+
cfs_mapping=self.cfs_mapping,
|
|
1890
|
+
supplier_info=supplier_info,
|
|
1891
|
+
consumer_info=consumer_info,
|
|
1892
|
+
direction=direction,
|
|
1893
|
+
indices=[(supplier_idx, consumer_idx)],
|
|
1894
|
+
value=new_cf,
|
|
1895
|
+
uncertainty=agg_uncertainty,
|
|
1896
|
+
)
|
|
1897
|
+
else:
|
|
1898
|
+
self.logger.warning(
|
|
1899
|
+
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
1900
|
+
f"with candidate suppliers={candidate_supplier_locations} and consumers={candidate_consumer_locations}"
|
|
1742
1901
|
)
|
|
1743
|
-
else:
|
|
1744
|
-
self.logger.warning(
|
|
1745
|
-
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
1746
|
-
f"with candidate suppliers={candidate_supplier_locations} and consumers={candidate_consumer_locations}"
|
|
1747
|
-
)
|
|
1748
1902
|
|
|
1749
1903
|
# Pass 2
|
|
1750
1904
|
compute_cf_memoized = compute_cf_memoized_factory(
|
|
@@ -1760,35 +1914,36 @@ class EdgeLCIA:
|
|
|
1760
1914
|
required_consumer_fields=self.required_consumer_fields,
|
|
1761
1915
|
)
|
|
1762
1916
|
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
consumer_info,
|
|
1766
|
-
(candidate_suppliers, candidate_consumers),
|
|
1767
|
-
), edge_group in tqdm(
|
|
1768
|
-
grouped_edges.items(), desc="Processing contained groups (pass 2)"
|
|
1769
|
-
):
|
|
1770
|
-
new_cf, matched_cf_obj, agg_uncertainty = compute_cf_memoized(
|
|
1917
|
+
if len(grouped_edges) > 0:
|
|
1918
|
+
for (
|
|
1771
1919
|
supplier_info,
|
|
1772
1920
|
consumer_info,
|
|
1773
|
-
candidate_suppliers,
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
direction=direction,
|
|
1783
|
-
indices=[(supplier_idx, consumer_idx)],
|
|
1784
|
-
value=new_cf,
|
|
1785
|
-
uncertainty=agg_uncertainty,
|
|
1786
|
-
)
|
|
1787
|
-
else:
|
|
1788
|
-
self.logger.warning(
|
|
1789
|
-
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
1790
|
-
f"with candidate suppliers={candidate_suppliers} and consumers={candidate_consumers}"
|
|
1921
|
+
(candidate_suppliers, candidate_consumers),
|
|
1922
|
+
), edge_group in tqdm(
|
|
1923
|
+
grouped_edges.items(), desc="Processing contained groups (pass 2)"
|
|
1924
|
+
):
|
|
1925
|
+
new_cf, matched_cf_obj, agg_uncertainty = compute_cf_memoized(
|
|
1926
|
+
supplier_info,
|
|
1927
|
+
consumer_info,
|
|
1928
|
+
candidate_suppliers,
|
|
1929
|
+
candidate_consumers,
|
|
1791
1930
|
)
|
|
1931
|
+
if new_cf:
|
|
1932
|
+
for supplier_idx, consumer_idx in edge_group:
|
|
1933
|
+
add_cf_entry(
|
|
1934
|
+
cfs_mapping=self.cfs_mapping,
|
|
1935
|
+
supplier_info=dict(supplier_info),
|
|
1936
|
+
consumer_info=dict(consumer_info),
|
|
1937
|
+
direction=direction,
|
|
1938
|
+
indices=[(supplier_idx, consumer_idx)],
|
|
1939
|
+
value=new_cf,
|
|
1940
|
+
uncertainty=agg_uncertainty,
|
|
1941
|
+
)
|
|
1942
|
+
else:
|
|
1943
|
+
self.logger.warning(
|
|
1944
|
+
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
1945
|
+
f"with candidate suppliers={candidate_suppliers} and consumers={candidate_consumers}"
|
|
1946
|
+
)
|
|
1792
1947
|
|
|
1793
1948
|
self._update_unprocessed_edges()
|
|
1794
1949
|
|
|
@@ -1820,7 +1975,7 @@ class EdgeLCIA:
|
|
|
1820
1975
|
"""
|
|
1821
1976
|
|
|
1822
1977
|
self._initialize_weights()
|
|
1823
|
-
|
|
1978
|
+
logger.info("Handling remaining exchanges…")
|
|
1824
1979
|
|
|
1825
1980
|
cf_operators = {
|
|
1826
1981
|
cf["supplier"].get("operator", "equals") for cf in self.raw_cfs_data
|
|
@@ -1891,11 +2046,6 @@ class EdgeLCIA:
|
|
|
1891
2046
|
remaining_edges = []
|
|
1892
2047
|
|
|
1893
2048
|
for (consumer_location, supplier_location), edges in edges_index.items():
|
|
1894
|
-
if any(
|
|
1895
|
-
x in ("RoW", "RoE", "GLO")
|
|
1896
|
-
for x in (consumer_location, supplier_location)
|
|
1897
|
-
):
|
|
1898
|
-
continue
|
|
1899
2049
|
|
|
1900
2050
|
if supplier_location is None:
|
|
1901
2051
|
candidate_suppliers_locations = [
|
|
@@ -1945,51 +2095,56 @@ class EdgeLCIA:
|
|
|
1945
2095
|
)
|
|
1946
2096
|
|
|
1947
2097
|
# Pass 1
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
supplier_idx,
|
|
1972
|
-
consumer_idx,
|
|
1973
|
-
supplier_info,
|
|
1974
|
-
consumer_info,
|
|
1975
|
-
_,
|
|
1976
|
-
_,
|
|
1977
|
-
) in group_edges:
|
|
1978
|
-
add_cf_entry(
|
|
1979
|
-
cfs_mapping=self.cfs_mapping,
|
|
1980
|
-
supplier_info=supplier_info,
|
|
1981
|
-
consumer_info=consumer_info,
|
|
1982
|
-
direction=direction,
|
|
1983
|
-
indices=[(supplier_idx, consumer_idx)],
|
|
1984
|
-
value=new_cf,
|
|
1985
|
-
uncertainty=unc,
|
|
2098
|
+
if len(prefiltered_groups) > 0:
|
|
2099
|
+
for sig, group_edges in tqdm(
|
|
2100
|
+
prefiltered_groups.items(), desc="Processing global groups (pass 1)"
|
|
2101
|
+
):
|
|
2102
|
+
supplier_info = group_edges[0][2]
|
|
2103
|
+
consumer_info = group_edges[0][3]
|
|
2104
|
+
|
|
2105
|
+
new_cf, matched_cf_obj, agg_uncertainty = compute_average_cf(
|
|
2106
|
+
candidate_suppliers=global_locations,
|
|
2107
|
+
candidate_consumers=global_locations,
|
|
2108
|
+
supplier_info=supplier_info,
|
|
2109
|
+
consumer_info=consumer_info,
|
|
2110
|
+
required_supplier_fields=self.required_supplier_fields,
|
|
2111
|
+
required_consumer_fields=self.required_consumer_fields,
|
|
2112
|
+
cf_index=self.cf_index,
|
|
2113
|
+
)
|
|
2114
|
+
unc = (
|
|
2115
|
+
agg_uncertainty
|
|
2116
|
+
if agg_uncertainty is not None
|
|
2117
|
+
else (
|
|
2118
|
+
matched_cf_obj.get("uncertainty")
|
|
2119
|
+
if matched_cf_obj
|
|
2120
|
+
else None
|
|
1986
2121
|
)
|
|
1987
|
-
else:
|
|
1988
|
-
self.logger.warning(
|
|
1989
|
-
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
1990
|
-
f"with candidate suppliers={global_locations} and consumers={global_locations}"
|
|
1991
2122
|
)
|
|
1992
2123
|
|
|
2124
|
+
if new_cf:
|
|
2125
|
+
for (
|
|
2126
|
+
supplier_idx,
|
|
2127
|
+
consumer_idx,
|
|
2128
|
+
supplier_info,
|
|
2129
|
+
consumer_info,
|
|
2130
|
+
_,
|
|
2131
|
+
_,
|
|
2132
|
+
) in group_edges:
|
|
2133
|
+
add_cf_entry(
|
|
2134
|
+
cfs_mapping=self.cfs_mapping,
|
|
2135
|
+
supplier_info=supplier_info,
|
|
2136
|
+
consumer_info=consumer_info,
|
|
2137
|
+
direction=direction,
|
|
2138
|
+
indices=[(supplier_idx, consumer_idx)],
|
|
2139
|
+
value=new_cf,
|
|
2140
|
+
uncertainty=unc,
|
|
2141
|
+
)
|
|
2142
|
+
else:
|
|
2143
|
+
self.logger.warning(
|
|
2144
|
+
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
2145
|
+
f"with candidate suppliers={global_locations} and consumers={global_locations}"
|
|
2146
|
+
)
|
|
2147
|
+
|
|
1993
2148
|
# Pass 2
|
|
1994
2149
|
compute_cf_memoized = compute_cf_memoized_factory(
|
|
1995
2150
|
cf_index=self.cf_index,
|
|
@@ -2004,40 +2159,45 @@ class EdgeLCIA:
|
|
|
2004
2159
|
required_consumer_fields=self.required_consumer_fields,
|
|
2005
2160
|
)
|
|
2006
2161
|
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
consumer_info,
|
|
2010
|
-
(candidate_suppliers, candidate_consumers),
|
|
2011
|
-
), edge_group in tqdm(
|
|
2012
|
-
grouped_edges.items(), desc="Processing global groups (pass 2)"
|
|
2013
|
-
):
|
|
2014
|
-
new_cf, matched_cf_obj, agg_uncertainty = compute_cf_memoized(
|
|
2162
|
+
if len(grouped_edges) > 0:
|
|
2163
|
+
for (
|
|
2015
2164
|
supplier_info,
|
|
2016
2165
|
consumer_info,
|
|
2017
|
-
candidate_suppliers,
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
agg_uncertainty
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
uncertainty=unc,
|
|
2166
|
+
(candidate_suppliers, candidate_consumers),
|
|
2167
|
+
), edge_group in tqdm(
|
|
2168
|
+
grouped_edges.items(), desc="Processing global groups (pass 2)"
|
|
2169
|
+
):
|
|
2170
|
+
new_cf, matched_cf_obj, agg_uncertainty = compute_cf_memoized(
|
|
2171
|
+
supplier_info,
|
|
2172
|
+
consumer_info,
|
|
2173
|
+
candidate_suppliers,
|
|
2174
|
+
candidate_consumers,
|
|
2175
|
+
)
|
|
2176
|
+
unc = (
|
|
2177
|
+
agg_uncertainty
|
|
2178
|
+
if agg_uncertainty is not None
|
|
2179
|
+
else (
|
|
2180
|
+
matched_cf_obj.get("uncertainty")
|
|
2181
|
+
if matched_cf_obj
|
|
2182
|
+
else None
|
|
2035
2183
|
)
|
|
2036
|
-
else:
|
|
2037
|
-
self.logger.warning(
|
|
2038
|
-
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
2039
|
-
f"with candidate suppliers={candidate_suppliers} and consumers={candidate_consumers}"
|
|
2040
2184
|
)
|
|
2185
|
+
if new_cf:
|
|
2186
|
+
for supplier_idx, consumer_idx in edge_group:
|
|
2187
|
+
add_cf_entry(
|
|
2188
|
+
cfs_mapping=self.cfs_mapping,
|
|
2189
|
+
supplier_info=dict(supplier_info),
|
|
2190
|
+
consumer_info=dict(consumer_info),
|
|
2191
|
+
direction=direction,
|
|
2192
|
+
indices=[(supplier_idx, consumer_idx)],
|
|
2193
|
+
value=new_cf,
|
|
2194
|
+
uncertainty=unc,
|
|
2195
|
+
)
|
|
2196
|
+
else:
|
|
2197
|
+
self.logger.warning(
|
|
2198
|
+
f"Fallback CF could not be computed for supplier={supplier_info}, consumer={consumer_info} "
|
|
2199
|
+
f"with candidate suppliers={candidate_suppliers} and consumers={candidate_consumers}"
|
|
2200
|
+
)
|
|
2041
2201
|
|
|
2042
2202
|
self._update_unprocessed_edges()
|
|
2043
2203
|
|