Skip to content

Commit

Permalink
brightway2 export working - incl. graph traversal!
Browse files Browse the repository at this point in the history
  • Loading branch information
pjamesjoyce committed Feb 23, 2017
1 parent a6d0cac commit 82b7555
Show file tree
Hide file tree
Showing 77 changed files with 20,662 additions and 1,308 deletions.
Binary file added ParameterSet_SandboxTesting_input_file.xlsx
Binary file not shown.
1,862 changes: 1,862 additions & 0 deletions SandboxTesting_database_export.csv

Large diffs are not rendered by default.

1,171 changes: 1,171 additions & 0 deletions bw2_Sandbox_database_export.csv

Large diffs are not rendered by default.

Binary file added lcopt/__pycache__/bw2_export.cpython-35.pyc
Binary file not shown.
Binary file modified lcopt/__pycache__/interact.cpython-35.pyc
Binary file not shown.
Binary file modified lcopt/__pycache__/io.cpython-35.pyc
Binary file not shown.
Binary file modified lcopt/__pycache__/model.cpython-35.pyc
Binary file not shown.
36 changes: 36 additions & 0 deletions lcopt/bw2_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from lcopt.io import exchange_factory
from copy import deepcopy

class Bw2Exporter():

def __init__(self, modelInstance):
self.modelInstance = modelInstance

def export_to_bw2(self):

db = self.modelInstance.database['items']
name = self.modelInstance.database['name']

altbw2database = deepcopy(db)

products = list(filter(lambda x: altbw2database[x]['type']=='product', altbw2database))
processes = list(filter(lambda x: altbw2database[x]['type']=='process', altbw2database))


for p in products:
product = altbw2database[p]
product['type'] = 'process'
new_exchanges = [x for x in product['exchanges'] if x['type']!='production']
product['exchanges']=new_exchanges

#add external links
if 'ext_link' in product.keys():
product['exchanges'].append(exchange_factory(product['ext_link'], 'technosphere', 1, 1, 'external link to {}'.format(product['ext_link'][0])))

for p in processes:
process = altbw2database[p]
for e in process['exchanges']:
if e['type'] == 'production':
e['type'] = 'technosphere'

return name, altbw2database
126 changes: 109 additions & 17 deletions lcopt/interact.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from flask import Flask, request, render_template
import webbrowser
import json
from ast import literal_eval
from lcopt.io import exchange_factory

class FlaskSandbox():

Expand All @@ -17,6 +19,8 @@ def __init__(self, modelInstance):
'echo':self.echo,
'searchEcoinvent':self.searchEcoinvent,
'newConnection': self.newConnection,
'addInput':self.addInput,
'inputLookup':self.inputLookup,
}

#print (self.modelInstance.newVariable)
Expand Down Expand Up @@ -62,6 +66,7 @@ def get_sandbox_variables(self):

inputs = [x for x in product_codes if x not in intermediates]
input_map = dict(zip(inputs, [db[(m.database['name'],x)]['name'] for x in inputs]))
self.reverse_input_map = {value:key for key, value in input_map.items()}

label_map = {**input_map, **process_output_name_map}

Expand Down Expand Up @@ -90,20 +95,22 @@ def get_sandbox_variables(self):

input_duplicates = []

for c, column in enumerate(matrix.T):
for r, i in enumerate(column):
if i>0:
p_from = link_indices[r]
p_to = link_indices[c]
if p_from in inputs:
suffix = "__" + str(input_duplicates.count(p_from))
input_duplicates.append(p_from)
p_type = 'input'
else:
suffix = ""
p_type = 'intermediate'

self.links.append({'sourceID':p_from + suffix, 'targetID':p_to, 'type':p_type, 'amount':1, 'label':label_map[p_from]})
#check there is a matrix (new models won't have one until parameter_scan() is run)
if matrix != None:
for c, column in enumerate(matrix.T):
for r, i in enumerate(column):
if i>0:
p_from = link_indices[r]
p_to = link_indices[c]
if p_from in inputs:
suffix = "__" + str(input_duplicates.count(p_from))
input_duplicates.append(p_from)
p_type = 'input'
else:
suffix = ""
p_type = 'intermediate'

self.links.append({'sourceID':p_from + suffix, 'targetID':p_to, 'type':p_type, 'amount':1, 'label':label_map[p_from]})

#add extra nodes
while len(input_duplicates)>0:
Expand Down Expand Up @@ -150,14 +157,20 @@ def newProcess(self, postData):
exchanges = [{'name':output_name, 'type':'production', 'unit':unit}]
location ='GLO'
m.create_process(name, exchanges, location, unit)

self.modelInstance.parameter_scan()
print (m.database['items'][(m.database['name'], postData['uuid'])])

return "OK"

def newConnection(self, postData):

print(postData)
db = self.modelInstance.database
self.get_sandbox_variables()

source = postData['sourceId']
print(self.reverse_process_output_map[source])

target = postData['targetId']
label = postData['label']
new_exchange = {'amount': 1,
Expand All @@ -174,6 +187,69 @@ def newConnection(self, postData):

return "OK"

def addInput(self, postData):
print(postData)
my_targetId = postData['targetId']

my_name = postData['name']
my_type = postData['type']
my_unit = postData['unit']
my_location = postData['location']

m = self.modelInstance

exchange_to_link = m.get_exchange(my_name)

if exchange_to_link == False:

#Create the new product
if 'ext_link' in postData.keys():
my_ext_link = literal_eval(postData['ext_link'])
exchange_to_link = m.create_product (name = my_name, location =my_location , unit=my_unit, ext_link = my_ext_link)
print('created linked product')
else:
exchange_to_link = m.create_product (name = my_name, location =my_location , unit=my_unit)
print('created unlinked product')

#link the product
#this_exchange = m.get_exchange(my_name)
#print(this_exchange)
this_exchange_object = exchange_factory(exchange_to_link, 'technosphere', 1, 1, '{} exchange of {}'.format('technosphere', my_name))
#print (this_exchange_object)

target_item = m.database['items'][(m.database['name'], my_targetId)]
#[print(target_item)]
target_item['exchanges'].append(this_exchange_object)

#run the parameter scan
m.parameter_scan()


return "OK"

def inputLookup(self, postData):
m = self.modelInstance
myInput = m.database['items'][(m.database['name'], postData['code'])]

return_data = {}

if 'ext_link' in myInput.keys():
ext_link = myInput['ext_link']
ext_db = [x['items'] for x in m.external_databases if x['name'] == ext_link[0]][0]
full_link = ext_db[ext_link]
full_link_string = "{} {{{}}} [{}]".format(full_link['name'], full_link['location'], full_link['unit'])

return_data['isLinked']=True
return_data['ext_link']=str(ext_link)
return_data['ext_link_string'] = full_link_string
return_data['ext_link_unit'] = full_link['unit']
else:
print('This is an unlinked product')
return_data['isLinked']=False
return_data['unlinked_unit'] = myInput['unit']

return json.dumps(return_data)

def echo(self, postData):
data = {'message':'Hello from echo'}
return json.dumps(data)
Expand Down Expand Up @@ -217,8 +293,24 @@ def process_post():
def shutdown():
self.shutdown_server()
return render_template('shutdown.html')

@app.route('/inputs.json')
def inputs_as_json():
"""creates a json file of the reverse input map to send from the server"""
self.get_sandbox_variables()
# to_json = [x for x in self.reverse_input_map.keys()]
#to_json = reverse_input_map
to_json = [{'name':k, 'code': v} for k,v in self.reverse_input_map.items()]
input_json = json.dumps(to_json)
return input_json

@app.route('/testing')
def testbed():
return render_template('testbed.html')

url = 'http://127.0.0.1:5000'
webbrowser.open_new(url)

app.run()
print ("running from the module")
app.run()


12 changes: 10 additions & 2 deletions lcopt/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def get_exchange_from_database(name, database):
item = database['items'][key]
if item['name'] == name:
return (database.get('name'), item.get('code'))
return None
return False

# partial function to get the item from the default database
#get_exchange = partial(get_exchange_from_database, database=defaultDatabase)
Expand Down Expand Up @@ -72,7 +72,15 @@ def exchange_factory(input, type, amount, uncertainty, comment):

# Create an item data structure

def item_factory(name, type, unit='kg', exchanges=[], location='GLO', categories=[], **kwargs):
def item_factory(name, type, unit='kg', exchanges=None, location='GLO', categories=None, **kwargs):

if exchanges is None:
exchanges = []

if categories is None:
categories = []



to_hash = name + type+ unit + location
code = hashlib.md5(to_hash.encode('utf-8')).hexdigest()
Expand Down
14 changes: 12 additions & 2 deletions lcopt/model.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from lcopt.io import *
from lcopt.ipython_interactive import IFS
from lcopt.interact import FlaskSandbox
from lcopt.bw2_export import Bw2Exporter

from functools import partial
from collections import OrderedDict
import numpy as np
Expand Down Expand Up @@ -206,7 +208,7 @@ def create_process(self, name, exchanges, location ='GLO', unit='kg'):

this_exchange = self.get_exchange(exc_name)

if this_exchange == None:
if this_exchange == False:
my_unit = e.pop('unit', unit)

this_exchange = self.create_product(exc_name, location=location, unit=my_unit, **e)
Expand Down Expand Up @@ -251,6 +253,7 @@ def parameter_scan(self):
col_code = cr_list.index(e['input'][1])

elif e['type'] =='technosphere':
print(e)
row_code = cr_list.index(e['input'][1])
inputs.append((row_code, e['amount']))

Expand Down Expand Up @@ -653,4 +656,11 @@ def parameter_parsing():
if __name__ == 'lcopt.model':
url = 'http://127.0.0.1:5000'
webbrowser.open_new(url)
app.run(debug=False)
app.run(debug=False)


### Brightway2 ###

def export_to_bw2(self):
my_exporter = Bw2Exporter(self)
return my_exporter.export_to_bw2()
File renamed without changes.
1 change: 1 addition & 0 deletions lcopt/static/css/cdn_cache/bootstrap-dialog.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions lcopt/static/css/testing.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
.bs-example {
font-family: sans-serif;
position: relative;
margin: 100px;
}
.typeahead, .tt-query, .tt-hint {
border: 2px solid #CCCCCC;
border-radius: 8px;
font-size: 22px; /* Set input font size */
height: 30px;
line-height: 30px;
outline: medium none;
padding: 8px 12px;
width: 396px;
}
.typeahead {
background-color: #FFFFFF;
}
.typeahead:focus {
border: 2px solid #0097CF;
}
.tt-query {
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
}
.tt-hint {
color: #999999;
}
.tt-menu {
background-color: #FFFFFF;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 8px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
margin-top: 12px;
padding: 8px 0;
width: 422px;
}

.tt-header {
font-size: 22px; /* Set suggestion dropdown font size */
color: darkgrey;
padding: 3px 20px;
}
.tt-header p {
margin: 0;
}
.tt-footer {
font-size: 22px; /* Set suggestion dropdown font size */
padding: 3px 20px;
cursor: pointer;
}
.tt-footer p {
margin: 0;
}

.tt-suggestion {
font-size: 22px; /* Set suggestion dropdown font size */
padding: 3px 20px;
}
.tt-suggestion:hover {
cursor: pointer;
background-color: #0097CF;
color: #FFFFFF;
}
.tt-suggestion p {
margin: 0;
}

0 comments on commit 82b7555

Please sign in to comment.