Chris Mutel avatar Chris Mutel committed ca255e1

Add SimaPro import tests

Comments (0)

Files changed (13)

 include bw2data/*.py
 include bw2data/io/*.py
 include bw2data/proxies/*.py
-include bw2data/tests/*.py
+include bw2data/tests/*.py
+include bw2data/tests/fixtures/*.py
+recursive-include bw2data/tests/fixtures *.txt
+recursive-include bw2data/tests/fixtures *.xml

bw2data/io/import_simapro.py

             if self.db_name in databases:
                 self.log.warning("Overwriting database %s" % self.db_name)
             database = Database(self.db_name)
-        database.write(dict([(obj['code'], obj) for obj in data]))
+        database.write(dict([
+            ((self.db_name, obj['code']), obj) for obj in data
+        ]))
         database.process()
         return self.db_name, self.logfile
 
             'location': geo or self.default_geo,
             'categories': line[5].split('\\')
         }
-        data['code'] = (self.db_name, activity_hash(data))
+        data['code'] = activity_hash(data)
         return data
 
     def get_dataset_metadata(self, dataset):
         line = dataset[self.get_exchanges_index(dataset) + 1]
         return {
             'amount': float(line[1]),
-            'input': data['code'],
+            'input': (self.db_name, data['code']),
             'uncertainty type': 0,
             'type': 'production'
         }
 
         """
         self.foreground = dict([
-            ((ds['name'], ds['unit']), ds['code']) for ds in data
+            ((ds['name'], ds['unit']), (self.db_name, ds['code']))
+            for ds in data
         ])
 
     def load_background(self):
             exc["input"] = self.background[(exc["name"].lower(), exc["unit"],
                 exc['location'])]
             found = True
-        elif (exc["name"].lower(), exc["unit"], exc['location']) in \
-                self.background:
-            exc["input"] = self.background[(exc["name"].lower(), exc["unit"],
-                exc['location'])]
+        elif (exc["name"].lower(), exc["unit"]) in self.background:
+            exc["input"] = self.background[(exc["name"].lower(), exc["unit"])]
             found = True
         else:
             found = False

bw2data/tests/__init__.py

 from .utils import UtilsTest
 from .array import ArrayProxyTest, ListArrayProxyTest
 from .sparse import SparseMatrixProxyTest
+from .simapro import SimaProImportTest

bw2data/tests/fixtures.py

-biosphere = {
-    ("biosphere", 1): {
-        'categories': ['things'],
-        'code': 1,
-        'exchanges': [],
-        'name': 'an emission',
-        'type': 'emission',
-        'unit': 'kg'
-        },
-    ("biosphere", 2): {
-        'categories': ['things'],
-        'code': 2,
-        'exchanges': [],
-        'type': 'emission',
-        'name': 'another emission',
-        'unit': 'kg'
-        },
-}
-
-food = {
-    ("food", 1): {
-        'categories': ['stuff', 'meals'],
-        'code': 1,
-        'exchanges': [{
-            'amount': 0.5,
-            'input': ('food', 2),
-            'type': 'technosphere',
-            'uncertainty type': 0},
-            {'amount': 0.05,
-            'input': ('biosphere', 1),
-            'type': 'biosphere',
-            'uncertainty type': 0}],
-        'location': 'CA',
-        'name': 'lunch',
-        'type': 'process',
-        'unit': 'kg'
-        },
-    ("food", 2): {
-        'categories': ['stuff', 'meals'],
-        'code': 2,
-        'exchanges': [{
-            'amount': 0.25,
-            'input': ('food', 1),
-            'type': 'technosphere',
-            'uncertainty type': 0},
-            {'amount': 0.15,
-            'input': ('biosphere', 2),
-            'type': 'biosphere',
-            'uncertainty type': 0}],
-        'location': 'CH',
-        'name': 'dinner',
-        'type': 'process',
-        'unit': 'kg'
-        },
-    }

bw2data/tests/fixtures/__init__.py

+biosphere = {
+    ("biosphere", 1): {
+        'categories': ['things'],
+        'code': 1,
+        'exchanges': [],
+        'name': 'an emission',
+        'type': 'emission',
+        'unit': 'kg'
+        },
+    ("biosphere", 2): {
+        'categories': ['things'],
+        'code': 2,
+        'exchanges': [],
+        'type': 'emission',
+        'name': 'another emission',
+        'unit': 'kg'
+        },
+}
+
+food = {
+    ("food", 1): {
+        'categories': ['stuff', 'meals'],
+        'code': 1,
+        'exchanges': [{
+            'amount': 0.5,
+            'input': ('food', 2),
+            'type': 'technosphere',
+            'uncertainty type': 0},
+            {'amount': 0.05,
+            'input': ('biosphere', 1),
+            'type': 'biosphere',
+            'uncertainty type': 0}],
+        'location': 'CA',
+        'name': 'lunch',
+        'type': 'process',
+        'unit': 'kg'
+        },
+    ("food", 2): {
+        'categories': ['stuff', 'meals'],
+        'code': 2,
+        'exchanges': [{
+            'amount': 0.25,
+            'input': ('food', 1),
+            'type': 'technosphere',
+            'uncertainty type': 0},
+            {'amount': 0.15,
+            'input': ('biosphere', 2),
+            'type': 'biosphere',
+            'uncertainty type': 0}],
+        'location': 'CH',
+        'name': 'dinner',
+        'type': 'process',
+        'unit': 'kg'
+        },
+    }

bw2data/tests/fixtures/simapro/empty.txt

+SimaPro don't even know	processes	Date:	29.08.2013	Time:	00:00:00
+Project	W00t
+
+
+Process
+
+Category type	material
+Process identifier	InsertSomethingCleverHere
+Type	Unit process
+Process name	bikes rule, cars drool
+Status
+Time period
+Geography
+Technology
+Representativeness
+Multiple output allocation
+Substitution allocation
+Cut off rules
+Capital goods
+Boundary with nature
+Infrastructure
+Date
+Record
+Generator
+Literature references
+Collection method
+Data treatment
+Verification
+Comment
+Allocation rules
+System description
+
+
+Products
+Fish food	1	p	100	not defined	Agricultural\Animal production\Animal foods
+
+Avoided products
+
+Resources
+
+Materials/fuels
+
+Electricity/heat
+
+Emissions to air
+
+Emissions to water
+
+Emissions to soil
+
+Final waste flows
+
+Non material emissions
+
+Social issues
+
+Economic issues
+
+Waste to treatment

bw2data/tests/fixtures/simapro/invalid.txt

+Joe's LCA Software	processes	Date:	29.08.2013	Time:	00:00:00
+Project	W00t
+
+
+Process
+
+Category type	material
+Process identifier	InsertSomethingCleverHere
+Type	Unit process
+Process name	bikes rule, cars drool
+Status	
+Time period	Unspecified
+Geography	Unspecified
+Technology	Unspecified
+Representativeness	Unspecified
+Multiple output allocation	Unspecified
+Substitution allocation	Unspecified
+Cut off rules	Unspecified
+Capital goods	Unspecified
+Boundary with nature	Unspecified
+Infrastructure	No
+Date	09.08.2013
+Record	
+Generator	
+Literature references
+Collection method	
+Data treatment	
+Verification	
+Comment	
+Allocation rules	
+System description	
+	
+
+Products
+Fish food	1	p	100	not defined	Agricultural\Animal production\Animal foods	
+
+Avoided products
+
+Resources
+
+Materials/fuels
+
+Electricity/heat
+
+Emissions to air
+
+Emissions to water
+
+Emissions to soil
+
+Final waste flows
+
+Non material emissions
+
+Social issues
+
+Economic issues
+
+Waste to treatment

bw2data/tests/fixtures/simapro/metadata.txt

+SimaPro don't even know	processes	Date:	29.08.2013	Time:	00:00:00
+Project	W00t
+
+
+Process
+
+Simple	yep!
+Multiline	This too
+	works just fine
+But stops	in time
+
+Products
+Fish food	1	p	100	not defined	Agricultural\Animal production\Animal foods
+
+Avoided products
+
+Resources
+
+Materials/fuels
+
+Electricity/heat
+
+Emissions to air
+
+Emissions to water
+
+Emissions to soil
+
+Final waste flows
+
+Non material emissions
+
+Social issues
+
+Economic issues
+
+Waste to treatment

bw2data/tests/fixtures/simapro/missing.txt

+SimaPro don't even know	processes	Date:	29.08.2013	Time:	00:00:00
+Project	W00t
+
+
+Process
+
+Category type	material
+Process identifier	InsertSomethingCleverHere
+Type	Unit process
+Process name	bikes rule, cars drool
+
+
+Products
+Fish food	1	p	100	not defined	Agricultural\Animal production\Animal foods
+
+Materials/fuels
+Dog food	1	p	Undefined
+
+Process
+
+Category type	material
+Process identifier	OopsForgot
+Type	Unit process
+Process name	raining cats and dogs
+
+
+Products
+Cat food	1	p	100	not defined	Agricultural\Animal production\Pet food
+
+Materials/fuels
+

bw2data/tests/fixtures/simapro/multioutput.txt

+SimaPro don't even know	processes	Date:	29.08.2013	Time:	00:00:00
+Project	W00t
+
+
+Process
+
+Category type	material
+Process identifier	InsertSomethingCleverHere
+Type	Unit process
+Process name	bikes rule, cars drool
+Status	
+Time period	Unspecified
+Geography	Unspecified
+Technology	Unspecified
+Representativeness	Unspecified
+Multiple output allocation	Unspecified
+Substitution allocation	Unspecified
+Cut off rules	Unspecified
+Capital goods	Unspecified
+Boundary with nature	Unspecified
+Infrastructure	No
+Date	09.08.2013
+Record	
+Generator	
+Literature references
+Collection method	
+Data treatment	
+Verification	
+Comment	
+Allocation rules	
+System description	
+	
+
+Products
+Fish food	1	p	100	not defined	Agricultural\Animal production\Animal foods	
+Turtle food	1	p	100	not defined	Agricultural\Animal production\Animal foods
+
+Avoided products
+
+Resources
+
+Materials/fuels
+
+Electricity/heat
+
+Emissions to air
+
+Emissions to water
+
+Emissions to soil
+
+Final waste flows
+
+Non material emissions
+
+Social issues
+
+Economic issues
+
+Waste to treatment

bw2data/tests/fixtures/simapro/simple.txt

+SimaPro don't even know	processes	Date:	29.08.2013	Time:	00:00:00
+Project	W00t
+
+
+Process
+
+Category type	material
+Process identifier	InsertSomethingCleverHere
+Type	Unit process
+Process name	bikes rule, cars drool
+
+
+Products
+Fish food	1	p	100	not defined	Agricultural\Animal production\Animal foods
+
+Materials/fuels
+lunch/CA U	1	kg	Undefined
+dinner	1	kg	Undefined
+Cat food	1	p	Undefined
+
+Process
+
+Category type	material
+Process identifier	OopsForgot
+Type	Unit process
+Process name	raining cats and dogs
+
+
+Products
+Cat food	1	p	100	not defined	Agricultural\Animal production\Pet food
+
+Materials/fuels
+dinner/CH/I S	1	kg	Undefined
+

bw2data/tests/fixtures/simapro_reference.py

+background = {
+    ("background", 1): {
+        'categories': ['stuff'],
+        'code': 1,
+        'exchanges': [],
+        'location': 'CA',
+        'name': 'lunch',
+        'type': 'process',
+        'unit': 'kilogram'
+        },
+    ("background", 2): {
+        'categories': ['stuff'],
+        'code': 2,
+        'exchanges': [],
+        'location': 'CH',
+        'name': 'dinner',
+        'type': 'process',
+        'unit': 'kilogram'
+        },
+    }

bw2data/tests/simapro.py

+# -*- coding: utf-8 -*-
+from . import BW2DataTest
+from .. import Database, databases
+from ..io.import_simapro import SimaProImporter, MissingExchange, detoxify_re
+from .fixtures.simapro_reference import background as background_data
+import os
+
+SP_FIXTURES_DIR = os.path.join(os.path.dirname(__file__), "fixtures", "simapro")
+
+
+class SimaProImportTest(BW2DataTest):
+    def filepath(self, name):
+        return os.path.join(SP_FIXTURES_DIR, name + '.txt')
+
+    def test_invalid_file(self):
+        sp = SimaProImporter(self.filepath("invalid"), depends=[])
+        data = sp.load_file()
+        with self.assertRaises(AssertionError):
+            sp.verify_simapro_file(data)
+
+    def test_overwrite(self):
+        database = Database("W00t")
+        database.register(format="", depends=[], num_processes=0)
+        sp = SimaProImporter(self.filepath("empty"), depends=[], overwrite=True)
+        sp.importer()
+        self.assertTrue("W00t" in databases)
+
+    def test_no_overwrite(self):
+        database = Database("W00t")
+        database.register(format="", depends=[], num_processes=0)
+        sp = SimaProImporter(self.filepath("empty"), depends=[])
+        with self.assertRaises(AssertionError):
+            sp.importer()
+
+    def test_import_one_empty_process(self):
+        sp = SimaProImporter(self.filepath("empty"), depends=[])
+        sp.importer()
+        self.assertTrue("W00t" in databases)
+        self.assertEqual(len(Database("W00t").load()), 1)
+
+    def test_get_db_name(self):
+        sp = SimaProImporter(self.filepath("empty"), depends=[])
+        sp.importer()
+        self.assertTrue("W00t" in databases)
+
+    def test_set_db_name(self):
+        sp = SimaProImporter(self.filepath("empty"), depends=[], name="A different one")
+        sp.importer()
+        self.assertTrue("A different one" in databases)
+        self.assertTrue("W00t" not in databases)
+
+    def test_default_geo(self):
+        sp = SimaProImporter(self.filepath("empty"), depends=[], default_geo="Where?")
+        sp.importer()
+        data = Database("W00t").load().values()[0]
+        self.assertEqual("Where?", data['location'])
+
+    def test_no_multioutput(self):
+        sp = SimaProImporter(self.filepath("multioutput"), depends=[])
+        with self.assertRaises(AssertionError):
+            sp.importer()
+
+    def test_detoxify_re(self):
+        self.assertFalse(detoxify_re.search("Cheese U"))
+        self.assertFalse(detoxify_re.search("Cheese/CH"))
+        self.assertTrue(detoxify_re.search("Cheese/CH U"))
+        self.assertTrue(detoxify_re.search("Cheese/CH/I U"))
+        self.assertTrue(detoxify_re.search("Cheese/CH/I S"))
+        self.assertTrue(detoxify_re.search("Cheese/RER U"))
+        self.assertTrue(detoxify_re.search("Cheese/CENTREL U"))
+        self.assertTrue(detoxify_re.search("Cheese/CENTREL S"))
+
+    def test_simapro_unit_conversion(self):
+        sp = SimaProImporter(self.filepath("empty"), depends=[])
+        sp.importer()
+        data = Database("W00t").load().values()[0]
+        self.assertEqual("unit", data['unit'])
+
+    def test_dataset_definition(self):
+        sp = SimaProImporter(self.filepath("empty"), depends=[])
+        sp.importer()
+        data = Database("W00t").load().values()[0]
+        self.assertEqual(data, {
+            "name": "Fish food",
+            "unit": "unit",
+            "location": "GLO",
+            "categories": ["Agricultural", "Animal production", "Animal foods"],
+            "code": u'6524377b64855cc3daf13bd1bcfe0385',
+            "exchanges": [{
+                'amount': 1.0,
+                'input': ('W00t', u'6524377b64855cc3daf13bd1bcfe0385'),
+                'type': 'production',
+                'uncertainty type': 0}],
+            "simapro metadata": {
+                "Category type": "material",
+                "Process identifier": "InsertSomethingCleverHere",
+                "Type": "Unit process",
+                "Process name": "bikes rule, cars drool",
+            }
+        })
+
+    def test_production_exchange(self):
+        sp = SimaProImporter(self.filepath("empty"), depends=[])
+        sp.importer()
+        data = Database("W00t").load().values()[0]
+        self.assertEqual(data['exchanges'], [{
+            'amount': 1.0,
+            'input': ('W00t', u'6524377b64855cc3daf13bd1bcfe0385'),
+            'type': 'production',
+            'uncertainty type': 0
+        }])
+
+    def test_simapro_metadata(self):
+        sp = SimaProImporter(self.filepath("metadata"), depends=[])
+        sp.importer()
+        data = Database("W00t").load().values()[0]
+        self.assertEqual(data['simapro metadata'], {
+            "Simple": "yep!",
+            "Multiline": ["This too", "works just fine"],
+            "But stops": "in time"
+        })
+
+    def test_linking(self):
+        # Test number of datasets
+        # Test internal links
+        # Test external links with and without slashes, with and without geo
+        database = Database("background")
+        database.register(
+            format="Test data",
+            depends=["background"],
+            num_processes=2
+        )
+        database.write(background_data)
+        sp = SimaProImporter(self.filepath("simple"), depends=["background"])
+        sp.importer()
+        # data = Database("W00t").load()
+
+    def test_missing(self):
+        sp = SimaProImporter(self.filepath("missing"), depends=[])
+        with self.assertRaises(MissingExchange):
+            sp.importer()
+
+    # Test multiple background DBs
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.