Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Massive change to use of locations and calculation of production volumes #154

Merged
merged 48 commits into from
Dec 19, 2018
Merged
Changes from 1 commit
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
4fbb1b4
Fix manual tests
cmutel Dec 11, 2018
70f8a04
Add default value for production_volume
cmutel Dec 11, 2018
150b39f
Change `annotate_exchange` to not clobber flow name
cmutel Dec 11, 2018
04a7151
Add preliminary version of market group finding
cmutel Dec 11, 2018
e31fa36
Merge branch 'master' into market_groups
cmutel Dec 11, 2018
4313dcb
Start documenting fixes to market groups
cmutel Dec 13, 2018
b12ddf3
Activities can go both ways (spicy!)
cmutel Dec 13, 2018
1100061
Validate no RoW market groups
cmutel Dec 13, 2018
0c2dfac
Start rewrite of market group linking
cmutel Dec 13, 2018
d74e751
Further progress on rewriting geolinking
cmutel Dec 13, 2018
66558d0
Fixing some tests for market groups
cmutel Dec 14, 2018
196823b
Fixes for topology.contained
cmutel Dec 14, 2018
5510522
Fix market groups tests
cmutel Dec 14, 2018
fcf0e1a
Docs updates
cmutel Dec 14, 2018
48de90f
More big changes to spatial functions and tests
cmutel Dec 14, 2018
c2e8e37
Fix a test
cmutel Dec 14, 2018
c0f8f83
Consistent and simpler RoW and GLO handling in tolopolgy functions
cmutel Dec 15, 2018
d262a17
RoW as backup supplier
cmutel Dec 15, 2018
e9219f8
Update docs
cmutel Dec 15, 2018
1ff93b2
Dont let zero amount dropped products break row label regrouping
cmutel Dec 15, 2018
33a3585
Correct a specific 3.3 bug
cmutel Dec 16, 2018
2595921
Add test combining resolved_row and subtract
cmutel Dec 16, 2018
b2492ed
Sort by topo faces with area proxy function
cmutel Dec 16, 2018
1ea1e50
Fix calculation of production volumes in market groups
cmutel Dec 17, 2018
36da8ad
Activities can consume from multiple markets - progress
cmutel Dec 17, 2018
1f1cfa1
Fix tests
cmutel Dec 17, 2018
85a2a98
Fix global activity consuming from multiple regional markets
cmutel Dec 17, 2018
7c44d55
Add topology speedups
cmutel Dec 17, 2018
f4ba806
Link markets and market groups simultaneously
cmutel Dec 17, 2018
10abed2
Misc cleanup
cmutel Dec 17, 2018
bf809ee
CZ in Europe
cmutel Dec 17, 2018
0c12d07
Use constructive_geometries
cmutel Dec 18, 2018
e5e43e9
Speed up ordered_dependencies
cmutel Dec 18, 2018
62820ad
Log subtracted activity links
cmutel Dec 18, 2018
52c4a51
Update PVs for transforming activities
cmutel Dec 18, 2018
e16b839
Market reference product suppliers must be contained
cmutel Dec 18, 2018
f983a56
Skip activity links for internal market losses
cmutel Dec 18, 2018
51a6b78
Link TA and MA with `link_consumers_to_markets`
cmutel Dec 18, 2018
abf0fdc
Delete faulty 3.5 activity link
cmutel Dec 18, 2018
3d6170c
Add more logging
cmutel Dec 18, 2018
871e572
Rename function
cmutel Dec 18, 2018
8845c83
Drop zero PV markets
cmutel Dec 18, 2018
94b0cf5
Correctly account for subtracted PVs in markets and GLO->RoW
cmutel Dec 19, 2018
799a632
Remove debugging and fix tests
cmutel Dec 19, 2018
6dae44f
Add missing dependency
cmutel Dec 19, 2018
f80abbc
Fix CI syntax error
cmutel Dec 19, 2018
5686f99
Another syntax fix
cmutel Dec 19, 2018
9d11684
Need to group by activity name, not reference product
cmutel Dec 19, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add more logging
cmutel committed Dec 18, 2018
commit 3d6170c2f2e49ed502559473eb8a3c662776328c
70 changes: 59 additions & 11 deletions ocelot/transformations/locations/linking.py
Original file line number Diff line number Diff line change
@@ -87,17 +87,28 @@ def link_consumers_to_recycled_content_activities(data):
}



def link_consumers_to_markets(data):
"""Link technosphere exchange inputs to markets and market groups.

Should only be run after ``add_suppliers_to_markets``. Skips hard (activity) links, and exchanges which have already been linked.

Add the field ``code`` to each exchange with the code of the linked market activity."""
no_mg_filter = lambda x: x['type'] != "market group"
filter_func = lambda x: x['type'] in ("market activity", "market group")
market_mapping = dict(toolz.groupby(
ma_filter = lambda x: x['type'] == "market activity"
ta_filter = lambda x: x['type'] == "transforming activity"
markets_filter = lambda x: x['type'] in ("market activity", "market group")
markets_mapping = dict(toolz.groupby(
'reference product',
filter(markets_filter, data)
))
ma_mapping = dict(toolz.groupby(
'reference product',
filter(filter_func, data)
filter(ma_filter, data)
))
ta_mapping = dict(toolz.groupby(
'reference product',
filter(ta_filter, data)
))

def annotate(exc, ds):
@@ -109,43 +120,65 @@ def annotate(exc, ds):
# Only unlinked (not recycled content or direct linked) technosphere inputs
loc = ds['location']

if loc == 'RoW':
if ds['type'] == 'transforming activity':
dct = ta_mapping
else:
dct = ma_mapping
consumer_row = topology.resolve_row(
[x['location'] for x in dct[ds['reference product']]]
)
else:
consumer_row = None

def contains_wrapper(consumer, supplier, found, consumer_row, supplier_row):
kwargs = {
'parent': consumer,
'child': supplier_row if supplier == 'RoW' else supplier,
'subtract': found,
'resolved_row': consumer_row if consumer == 'RoW' else None
}
return topology.contains(**kwargs)

for exc in list(filter(unlinked, ds['exchanges'])):
try:
candidates = market_mapping[exc['name']]
candidates = markets_mapping[exc['name']]
except KeyError:
if exc['name'] == 'refinery gas':
pass
else:
raise MissingSupplier("No markets found for product {}".format(exc['name']))

found, to_add = [], []

markets = {x['location']: x for x in candidates if x['type'] == 'market activity'}
market_groups = {x['location']: x for x in candidates if x['type'] == 'market group'}

if 'RoW' in markets:
resolved_market_row = topology.resolve_row(markets)
supplier_row = topology.resolve_row(markets)
else:
resolved_market_row = set()
supplier_row = set()

together = set(markets).union(set(market_groups))
ordered = topology.ordered_dependencies(
[{'location': l} for l in together],
resolved_market_row
supplier_row
)

for candidate in ordered:
if topology.contains(loc, candidate, subtract=found, resolved_row=resolved_market_row):
if contains_wrapper(loc, candidate, found, consumer_row, supplier_row):
found.append(candidate)
if candidate in markets:
to_add.append(markets[candidate])
else:
to_add.append(market_groups[candidate])

if (ds['name'] == 'yarn production, kenaf' and ds['location'] == 'RoW'):
print("Added:", candidate, [x['location'] for x in to_add])
if not found:
# No market or market group within this location -
# Find smallest market or market group which contains this activity
for candidate in reversed(ordered):
if topology.contains(candidate, loc, resolved_row=resolved_market_row):
if contains_wrapper(candidate, loc, found, supplier_row, consumer_row):
found.append(candidate)
if candidate in markets:
to_add.append(markets[candidate])
@@ -157,7 +190,7 @@ def annotate(exc, ds):
obj = to_add[0]
exc['code'] = obj['code']

message = "Link complete input of {} '{}' to '{}' ({})"
message = "Link complete input of {} '{}' from '{}' ({})"
detailed.info({
'ds': ds,
'message': message.format(
@@ -169,17 +202,32 @@ def annotate(exc, ds):
'function': 'link_consumers_to_markets'
})
else:
if (ds['name'] == 'yarn production, kenaf' and ds['location'] == 'RoW'):
print("Starting allocation:", len(to_add))
ds['suppliers'] = [annotate(exc, obj) for obj in to_add]

if not ds['suppliers']:
del ds['suppliers']
continue

if (ds['name'] == 'yarn production, kenaf' and ds['location'] == 'RoW'):
print("Suppliers:", [x['location'] for x in ds['suppliers']])

for e in ds['suppliers']:
logger.info({
'type': 'table element',
'data': (ds['name'], ds['location'], e['location'])
})
message = "Link consumption input of {} from '{}' ({})"
detailed.info({
'ds': ds,
'message': message.format(
exc['name'],
e['name'],
e['location']
),
'function': 'link_consumers_to_markets'
})

allocate_suppliers(ds, is_market=False, exc=exc)
del ds['suppliers']
12 changes: 12 additions & 0 deletions ocelot/transformations/locations/markets.py
Original file line number Diff line number Diff line change
@@ -196,6 +196,18 @@ def allocate_suppliers(dataset, is_market=True, exc=None):
'function': 'allocate_suppliers'
})
total_pv = dataset['suppliers'][0]['production volume']['amount'] = 4321
else:
message = "Production volume of {} {} divided into {} suppliers"
detailed.info({
'ds': dataset,
'message': message.format(
total_pv,
exc['name'],
len(dataset['suppliers']),
),
'function': 'allocate_suppliers'
})


for supply_exc in dataset['suppliers']:
scale_factor = supply_exc['production volume']['amount'] / total_pv