cetk 0.0.4.dev0__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.
Files changed (60) hide show
  1. cetk/__init__.py +87 -0
  2. cetk/db.py +41 -0
  3. cetk/edb/__init__.py +0 -0
  4. cetk/edb/apps.py +9 -0
  5. cetk/edb/cache.py +249 -0
  6. cetk/edb/const.py +26 -0
  7. cetk/edb/copy.py +18 -0
  8. cetk/edb/exporters.py +551 -0
  9. cetk/edb/importers/__init__.py +36 -0
  10. cetk/edb/importers/activity_import.py +279 -0
  11. cetk/edb/importers/codeset_import.py +124 -0
  12. cetk/edb/importers/gridsource_import.py +256 -0
  13. cetk/edb/importers/roadsource_import.py +1602 -0
  14. cetk/edb/importers/source_import.py +958 -0
  15. cetk/edb/importers/timevar_import.py +115 -0
  16. cetk/edb/importers/utils.py +92 -0
  17. cetk/edb/importers/validation.py +207 -0
  18. cetk/edb/ltreefield.py +76 -0
  19. cetk/edb/migrations/0001_initial.py +1731 -0
  20. cetk/edb/migrations/0002_data.py +156 -0
  21. cetk/edb/migrations/0003_create_gpkg_tables.py +14 -0
  22. cetk/edb/migrations/__init__.py +0 -0
  23. cetk/edb/models/__init__.py +49 -0
  24. cetk/edb/models/base.py +52 -0
  25. cetk/edb/models/common_models.py +144 -0
  26. cetk/edb/models/fleets.py +160 -0
  27. cetk/edb/models/gridsource_models.py +163 -0
  28. cetk/edb/models/road_classes.py +197 -0
  29. cetk/edb/models/road_models.py +413 -0
  30. cetk/edb/models/source_models.py +399 -0
  31. cetk/edb/models/timevar_models.py +111 -0
  32. cetk/edb/rasterize/__init__.py +1 -0
  33. cetk/edb/rasterize/rasterizer.py +1544 -0
  34. cetk/edb/signals.py +43 -0
  35. cetk/edb/traffic.py +75 -0
  36. cetk/edb/units.py +160 -0
  37. cetk/emissions/__init__.py +0 -0
  38. cetk/emissions/aggregate_emissions.sql +303 -0
  39. cetk/emissions/areasource_emissions.sql +53 -0
  40. cetk/emissions/calc.py +148 -0
  41. cetk/emissions/filters.py +179 -0
  42. cetk/emissions/gridsource_emissions.sql +52 -0
  43. cetk/emissions/pointsource_emissions.sql +53 -0
  44. cetk/emissions/queries.py +221 -0
  45. cetk/emissions/roadsource_emissions.sql +211 -0
  46. cetk/emissions/used_substances.sql +56 -0
  47. cetk/emissions/views.py +89 -0
  48. cetk/logging.py +68 -0
  49. cetk/settings.py +85 -0
  50. cetk/tools/__init__.py +1 -0
  51. cetk/tools/cetk_command.py +599 -0
  52. cetk/tools/manage.py +24 -0
  53. cetk/tools/utils.py +334 -0
  54. cetk/utils.py +62 -0
  55. cetk-0.0.4.dev0.dist-info/LICENSE +201 -0
  56. cetk-0.0.4.dev0.dist-info/METADATA +297 -0
  57. cetk-0.0.4.dev0.dist-info/RECORD +60 -0
  58. cetk-0.0.4.dev0.dist-info/WHEEL +5 -0
  59. cetk-0.0.4.dev0.dist-info/entry_points.txt +3 -0
  60. cetk-0.0.4.dev0.dist-info/top_level.txt +1 -0
cetk/edb/exporters.py ADDED
@@ -0,0 +1,551 @@
1
+ import ast
2
+ import os
3
+
4
+ # need to import fiona before geopandas due to gpd bug causing circular imports.
5
+ import fiona # noqa
6
+ import geopandas as gpd
7
+ import numpy as np
8
+ import pandas as pd
9
+ import pyogrio
10
+ import rasterio as rio
11
+ from django.db import connection
12
+ from openpyxl import Workbook
13
+ from shapely import wkt
14
+
15
+ from cetk.edb.const import DEFAULT_EMISSION_UNIT, WGS84_SRID
16
+ from cetk.edb.importers.source_import import (
17
+ OPTIONAL_COLUMNS_POINT,
18
+ REQUIRED_COLUMNS_AREA,
19
+ REQUIRED_COLUMNS_POINT,
20
+ )
21
+ from cetk.edb.models import (
22
+ Activity,
23
+ ActivityCode,
24
+ AreaSource,
25
+ AreaSourceSubstance,
26
+ CodeSet,
27
+ ColdstartTimevar,
28
+ CongestionProfile,
29
+ EmissionFactor,
30
+ Facility,
31
+ Fleet,
32
+ FleetMemberFuel,
33
+ FlowTimevar,
34
+ GridSource,
35
+ GridSourceSubstance,
36
+ PointSource,
37
+ PointSourceSubstance,
38
+ RoadAttribute,
39
+ RoadClass,
40
+ RoadSource,
41
+ Substance,
42
+ TrafficSituation,
43
+ VehicleEF,
44
+ VehicleFuel,
45
+ VehicleFuelComb,
46
+ )
47
+ from cetk.edb.models.timevar_models import Timevar
48
+ from cetk.edb.units import activity_rate_unit_from_si, emis_conversion_factor_from_si
49
+ from cetk.tools.utils import get_db
50
+
51
+ REQUIRED_COLUMNS_GRID = {
52
+ "name": np.str_,
53
+ "rastername": np.str_,
54
+ "timevar": np.str_,
55
+ "path": np.str_,
56
+ }
57
+
58
+ days_header = [
59
+ "ID",
60
+ "typeday",
61
+ "monday",
62
+ "tuesday",
63
+ "wednesday",
64
+ "thursday",
65
+ "friday",
66
+ "saturday",
67
+ "sunday",
68
+ ]
69
+ months_header = [
70
+ " ",
71
+ "month",
72
+ "January",
73
+ "February",
74
+ "March",
75
+ "April",
76
+ "May",
77
+ "June",
78
+ "July",
79
+ "August",
80
+ "September",
81
+ "October",
82
+ "November",
83
+ "December",
84
+ ]
85
+ time_intervals = [
86
+ "00-01",
87
+ "01-02",
88
+ "02-03",
89
+ "03-04",
90
+ "04-05",
91
+ "05-06",
92
+ "06-07",
93
+ "07-08",
94
+ "08-09",
95
+ "09-10",
96
+ "10-11",
97
+ "11-12",
98
+ "12-13",
99
+ "13-14",
100
+ "14-15",
101
+ "15-16",
102
+ "16-17",
103
+ "17-18",
104
+ "18-19",
105
+ "19-20",
106
+ "20-21",
107
+ "21-22",
108
+ "22-23",
109
+ "23-24",
110
+ ]
111
+
112
+
113
+ def export_sources(export_filepath, srid=WGS84_SRID, unit=DEFAULT_EMISSION_UNIT):
114
+ # Create a new Excel workbook and remove standard first Sheet
115
+ workbook = Workbook()
116
+ del workbook["Sheet"]
117
+ if PointSource.objects.count() > 0:
118
+ point_columns = REQUIRED_COLUMNS_POINT | OPTIONAL_COLUMNS_POINT
119
+ worksheet = workbook.create_sheet(title="PointSource")
120
+ create_source_sheet(
121
+ worksheet, PointSource, point_columns, PointSourceSubstance, unit
122
+ )
123
+ workbook.save(export_filepath)
124
+
125
+ if AreaSource.objects.count() > 0:
126
+ worksheet = workbook.create_sheet(title="AreaSource")
127
+ create_source_sheet(
128
+ worksheet, AreaSource, REQUIRED_COLUMNS_AREA, AreaSourceSubstance, unit
129
+ )
130
+ workbook.save(export_filepath)
131
+
132
+ if GridSource.objects.count() > 0:
133
+ worksheet = workbook.create_sheet(title="GridSource")
134
+ create_source_sheet(
135
+ worksheet, GridSource, REQUIRED_COLUMNS_GRID, GridSourceSubstance, unit
136
+ )
137
+ workbook.save(export_filepath)
138
+
139
+ if EmissionFactor.objects.count() > 0:
140
+ worksheet = workbook.create_sheet(title="EmissionFactor")
141
+ header = [
142
+ "activity_name",
143
+ "substance",
144
+ "factor",
145
+ "emissionfactor_unit",
146
+ "activity_unit",
147
+ ]
148
+ worksheet.append(header)
149
+ for emfac in EmissionFactor.objects.all():
150
+ # all factors stored in SI, original factor unit at import not stored in db.
151
+ factor_unit = "kg/" + emfac.activity.unit.split("/")[0]
152
+ row_data = [
153
+ emfac.activity.name,
154
+ emfac.substance.slug,
155
+ emfac.factor,
156
+ factor_unit,
157
+ emfac.activity.unit,
158
+ ]
159
+ worksheet.append(row_data)
160
+ workbook.save(export_filepath)
161
+
162
+ if CodeSet.objects.count() > 0:
163
+ worksheet = workbook.create_sheet(title="CodeSet")
164
+ header = ["name", "slug", "description"]
165
+ worksheet.append(header)
166
+ for cs in CodeSet.objects.all():
167
+ worksheet.append([cs.name, cs.slug, cs.description])
168
+ workbook.save(export_filepath)
169
+
170
+ if ActivityCode.objects.count() > 0:
171
+ worksheet = workbook.create_sheet(title="ActivityCode")
172
+ header = ["codeset_slug", "activitycode", "label", "vertical_distribution_slug"]
173
+ worksheet.append(header)
174
+ for ac in ActivityCode.objects.all():
175
+ if ac.vertical_dist is not None:
176
+ worksheet.append(
177
+ [ac.code_set.slug, ac.code, ac.label, ac.vertical_dist.slug]
178
+ )
179
+ else:
180
+ worksheet.append([ac.code_set.slug, ac.code, ac.label, ""])
181
+ workbook.save(export_filepath)
182
+
183
+ if Timevar.objects.count() > 0:
184
+ worksheet = workbook.create_sheet(title="Timevar")
185
+ create_timevar_sheet(worksheet, Timevar)
186
+ workbook.save(export_filepath)
187
+
188
+ if FlowTimevar.objects.count() > 0:
189
+ worksheet = workbook.create_sheet(title="FlowTimevar")
190
+ create_timevar_sheet(worksheet, FlowTimevar)
191
+ workbook.save(export_filepath)
192
+
193
+ if ColdstartTimevar.objects.count() > 0:
194
+ worksheet = workbook.create_sheet(title="ColdstartTimevar")
195
+ create_timevar_sheet(worksheet, ColdstartTimevar)
196
+ workbook.save(export_filepath)
197
+
198
+ if CongestionProfile.objects.count() > 0:
199
+ worksheet = workbook.create_sheet(title="CongestionProfile")
200
+ create_timevar_sheet(worksheet, CongestionProfile)
201
+ workbook.save(export_filepath)
202
+
203
+ if RoadSource.objects.count() > 0:
204
+ create_roadsource_sheet(workbook)
205
+ workbook.save(export_filepath)
206
+
207
+ # RoadAttributes could be defined before importing any roads
208
+ if RoadAttribute.objects.count() > 0:
209
+ worksheet = workbook.create_sheet(title="RoadAttribute")
210
+ header = ["name", "slug"]
211
+ worksheet.append(header)
212
+ for ra in RoadAttribute.objects.all():
213
+ worksheet.append([ra.name, ra.slug])
214
+ workbook.save(export_filepath)
215
+
216
+ if VehicleFuelComb.objects.count() > 0:
217
+ create_vehiclefuel_sheet(workbook)
218
+ workbook.save(export_filepath)
219
+
220
+ if Fleet.objects.count() > 0:
221
+ create_fleet_sheet(workbook)
222
+ workbook.save(export_filepath)
223
+
224
+ if TrafficSituation.objects.count() > 0:
225
+ create_traffic_sheet(workbook)
226
+ workbook.save(export_filepath)
227
+
228
+ if VehicleEF.objects.count() > 0:
229
+ create_vehicle_ef_sheet(workbook)
230
+ workbook.save(export_filepath)
231
+
232
+
233
+ def create_vehicle_ef_sheet(workbook):
234
+ worksheet = workbook.create_sheet(title="VehicleEmissionFactor")
235
+ header = [
236
+ "traffic_situation",
237
+ "vehicle",
238
+ "fuel",
239
+ "substance",
240
+ "freeflow",
241
+ "heavy",
242
+ "saturated",
243
+ "stopngo",
244
+ "coldstart",
245
+ "unit",
246
+ ]
247
+ worksheet.append(header)
248
+ for vef in VehicleEF.objects.all():
249
+ # TODO could convert to more human readable values with for example unit mg/km.
250
+ row = [
251
+ vef.traffic_situation.ts_id,
252
+ vef.vehicle.name,
253
+ vef.fuel.name,
254
+ vef.substance.slug,
255
+ vef.freeflow,
256
+ vef.heavy,
257
+ vef.saturated,
258
+ vef.stopngo,
259
+ vef.coldstart,
260
+ "kg/m",
261
+ ]
262
+ worksheet.append(row)
263
+
264
+
265
+ def create_traffic_sheet(workbook):
266
+ worksheet = workbook.create_sheet(title="TrafficSituation")
267
+ header = ["traffic_situation"]
268
+ attributes = []
269
+ for attribute in RoadAttribute.objects.all():
270
+ header.append("attr:" + attribute.slug)
271
+ attributes.append(attribute.slug)
272
+ attributes = np.array(attributes)
273
+ worksheet.append(header)
274
+ for i, rc in enumerate(RoadClass.objects.all()):
275
+ row = [""] * len(header)
276
+ row[0] = rc.traffic_situation.ts_id
277
+ for av in rc.attribute_values.all():
278
+ ind = np.where(attributes == av.attribute.slug)[0][0]
279
+ row[ind + 1] = av.value
280
+ worksheet.append(row)
281
+
282
+
283
+ def create_fleet_sheet(workbook):
284
+ worksheet = workbook.create_sheet(title="Fleet")
285
+ header = [
286
+ "name",
287
+ "default_heavy_vehicle_share",
288
+ "vehicle",
289
+ "vehicle_fraction",
290
+ "coldstart_fraction",
291
+ "flow_timevar",
292
+ "coldstart_timevar",
293
+ ]
294
+ fuel_ids = []
295
+ for fuel in VehicleFuel.objects.all():
296
+ fuel_ids.append(fuel.id)
297
+ header.append(f"fuel:{fuel.name}")
298
+ worksheet.append(header)
299
+ for fleet in Fleet.objects.all():
300
+ for fleetmember in fleet.vehicles.all():
301
+ veh = fleetmember.vehicle
302
+ row = [
303
+ fleet.name,
304
+ fleet.default_heavy_vehicle_share,
305
+ veh.name,
306
+ fleetmember.fraction,
307
+ fleetmember.coldstart_fraction,
308
+ ]
309
+ if fleetmember.timevar is None:
310
+ row.append("")
311
+ else:
312
+ row.append(fleetmember.timevar.name)
313
+ if fleetmember.coldstart_timevar is None:
314
+ row.append("")
315
+ else:
316
+ row.append(fleetmember.coldstart_timevar.name)
317
+ for fuel_id in fuel_ids:
318
+ try:
319
+ row.append(fleetmember.fuels.get(fuel_id=fuel_id).fraction)
320
+ except FleetMemberFuel.DoesNotExist:
321
+ row.append("")
322
+ worksheet.append(row)
323
+
324
+
325
+ def create_vehiclefuel_sheet(workbook):
326
+ worksheet = workbook.create_sheet(title="VehicleFuel")
327
+ header = ["name", "isheavy", "info", "fuel"]
328
+ codeset_slugs = [code.slug for code in CodeSet.objects.all()]
329
+ codeset_ids = [CodeSet.objects.get(slug=slug).id for slug in codeset_slugs]
330
+ codeset_columns = [f"activitycode_{slug}" for slug in codeset_slugs]
331
+ header = header + codeset_columns
332
+ worksheet.append(header)
333
+ for vf in VehicleFuelComb.objects.all():
334
+ row = [vf.vehicle.name, str(vf.vehicle.isheavy), vf.vehicle.info, vf.fuel.name]
335
+ for i in codeset_ids:
336
+ try:
337
+ row.append(
338
+ ActivityCode.objects.get(id=getattr(vf, f"activitycode{i}_id")).code
339
+ )
340
+ except ActivityCode.DoesNotExist:
341
+ row.append("")
342
+ worksheet.append(row)
343
+
344
+
345
+ def create_roadsource_sheet(workbook):
346
+ worksheet = workbook.create_sheet(title="RoadSource")
347
+ header = [
348
+ "filepath",
349
+ "name",
350
+ "nlanes",
351
+ "width",
352
+ "median_strip_width",
353
+ "aadt",
354
+ "heavy_vehicle_share",
355
+ "fleet",
356
+ "congestion_profile",
357
+ "speed",
358
+ "slope",
359
+ ]
360
+ # add attributes, always at least 1 to define which emission factors to use
361
+ road_attributes = ""
362
+ for attribute in RoadAttribute.objects.all():
363
+ header.append("attr:" + attribute.slug)
364
+ road_attributes += f", rc.{attribute.slug} AS {attribute.slug} "
365
+ worksheet.append(header)
366
+ # slight adaptions to header to form actual content
367
+ db_name = os.path.basename(get_db()).split(".")[0]
368
+ roadpath = os.path.join(os.path.dirname(get_db()), db_name + "-roadsource.gpkg")
369
+ header[0] = roadpath
370
+ header = [attr.replace("attr:", "") for attr in header]
371
+ worksheet.append(header)
372
+
373
+ sql = (
374
+ "SELECT rs.name, rs.nolanes, rs.width, rs.median_strip_width, rs.aadt, "
375
+ "rs.heavy_vehicle_share, f.name AS fleet, cp.name AS congestion_profile, "
376
+ "rs.speed, rs.slope, rs.roadclass_id, ST_AsText(geom) AS geometry "
377
+ "FROM edb_roadsource AS rs "
378
+ "LEFT JOIN edb_fleet AS F ON rs.fleet_id = f.id "
379
+ "LEFT JOIN edb_congestionprofile AS cp ON rs.congestion_profile_id = cp.id "
380
+ )
381
+ cur = connection.cursor()
382
+ cur.execute(sql)
383
+
384
+ df = pd.DataFrame(cur.fetchall(), columns=[col[0] for col in cur.description])
385
+ roadclass_mapping = {}
386
+ for rc in RoadClass.objects.all():
387
+ roadclass_mapping[rc.id] = rc.attributes
388
+ for col in roadclass_mapping[1].keys():
389
+ df[col] = df["roadclass_id"].map(
390
+ lambda x: roadclass_mapping[x][col] if x in roadclass_mapping else None
391
+ )
392
+ df = df.drop(columns=["roadclass_id"])
393
+ df["geometry"] = df["geometry"].apply(wkt.loads)
394
+ gdf = gpd.GeoDataFrame(df, geometry="geometry")
395
+ crs = "EPSG:4326"
396
+ gdf.crs = crs
397
+ # does not work from QGIS gdf.to_file(roadpath, driver="GPKG")
398
+ pyogrio.write_dataframe(gdf, roadpath, layer="roads")
399
+
400
+
401
+ def create_timevar_sheet(worksheet, tvar_type):
402
+ for tvar in tvar_type.objects.all():
403
+ worksheet.append(days_header)
404
+ if tvar_type is CongestionProfile:
405
+ typeday_list = ast.literal_eval(tvar.traffic_condition)
406
+ else:
407
+ typeday_list = ast.literal_eval(tvar.typeday)
408
+ for i in range(len(typeday_list)):
409
+ if i == 0:
410
+ row_data = [tvar.name] + [time_intervals[i]] + typeday_list[i]
411
+ else:
412
+ row_data = [""] + [time_intervals[i]] + typeday_list[i]
413
+ worksheet.append(row_data)
414
+ if tvar_type is not CongestionProfile:
415
+ month_list = ast.literal_eval(tvar.month)
416
+ worksheet.append(months_header)
417
+ worksheet.append(["", ""] + month_list)
418
+
419
+
420
+ def create_source_sheet(
421
+ worksheet, model_type, REQUIRED_COLUMNS, SourceSubstanceModel, unit
422
+ ):
423
+ """create source sheet for Point, Area or GridSource"""
424
+ emis_conversion_factor = emis_conversion_factor_from_si(unit)
425
+ header = list(REQUIRED_COLUMNS.keys())
426
+ codeset_slugs = [code.slug for code in CodeSet.objects.all()]
427
+ codeset_ids = [CodeSet.objects.get(slug=slug).id for slug in codeset_slugs]
428
+ codeset_columns = [f"activitycode_{slug}" for slug in codeset_slugs]
429
+ substance_slugs = list(
430
+ set([ss.substance.slug for ss in SourceSubstanceModel.objects.all()])
431
+ )
432
+ substance_columns = [f"subst:{subst}" for subst in substance_slugs]
433
+ header = header + codeset_columns + substance_columns + ["emission_unit"]
434
+ activities = Activity.objects.all()
435
+ if len(activities) > 0:
436
+ activity_names = [activity.name for activity in activities]
437
+ activity_columns = [f"act:{name}" for name in activity_names]
438
+ header = header + activity_columns
439
+
440
+ worksheet.append(header)
441
+ for source in model_type.objects.all():
442
+ if source.timevar_id is not None:
443
+ timevar_name = Timevar.objects.get(id=source.timevar_id).name
444
+ else:
445
+ timevar_name = ""
446
+
447
+ activitycodes = {}
448
+ for i in codeset_ids:
449
+ activitycode = getattr(source, f"activitycode{i}")
450
+ activitycodes[i] = activitycode.code if activitycode is not None else ""
451
+ source_substances = [ss.substance.slug for ss in source.substances.all()]
452
+ if model_type == GridSource:
453
+ if len(source_substances) > 0:
454
+ rasternames = set(
455
+ [substance.raster for substance in source.substances.all()]
456
+ )
457
+ if len(rasternames) == 1:
458
+ rastername = source.substances.first().raster
459
+ else:
460
+ try:
461
+ rastername = (
462
+ os.path.commonprefix(list(rasternames))
463
+ + "{subst}"
464
+ + common_suffix(list(rasternames))
465
+ )
466
+ except Exception:
467
+ raise ValueError(
468
+ "Could not find a generic raster name "
469
+ + f"for GridSource {source.name}"
470
+ )
471
+ elif source.activities.count() > 0:
472
+ rastername = source.activities.first().raster
473
+ rasternames = [rastername]
474
+ else:
475
+ rastername = ""
476
+ if rastername != "":
477
+ rasterpath = os.path.join(
478
+ os.path.dirname(get_db()), rastername + ".tif"
479
+ )
480
+ for name in rasternames:
481
+ # storing each raster, not generic name
482
+ tif_path = os.path.join(os.path.dirname(get_db()), name + ".tif")
483
+ with rio.open(f"GPKG:{get_db()}:raster_{name}") as src:
484
+ meta = src.meta
485
+ meta.update(driver="GTiff")
486
+ with rio.open(tif_path, "w", **meta) as dst:
487
+ # always only 1 band
488
+ dst.write(src.read(1), 1)
489
+ else:
490
+ rasterpath = ""
491
+ row_data = [source.name, rastername, timevar_name, rasterpath]
492
+ else:
493
+ row_data = [
494
+ str(source.facility),
495
+ Facility.objects.get(id=source.facility_id).name,
496
+ source.name,
497
+ source.geom.coords[1] if model_type == PointSource else source.geom.wkt,
498
+ ]
499
+ if model_type == PointSource:
500
+ row_data.append(source.geom.coords[0])
501
+ row_data.append(timevar_name)
502
+
503
+ if hasattr(source, "chimney_height"):
504
+ row_data.extend(
505
+ [
506
+ source.chimney_height,
507
+ source.chimney_outer_diameter,
508
+ source.chimney_inner_diameter,
509
+ source.chimney_gas_speed,
510
+ source.chimney_gas_temperature,
511
+ source.house_width,
512
+ source.house_height,
513
+ ]
514
+ )
515
+
516
+ for i in codeset_ids:
517
+ row_data.append(activitycodes[i])
518
+
519
+ emis_row = [
520
+ source.substances.get(substance=Substance.objects.get(slug=slug).id).value
521
+ if slug in source_substances
522
+ else 0
523
+ for slug in substance_slugs
524
+ ]
525
+ emis_row = [emis * emis_conversion_factor for emis in emis_row]
526
+ row_data = row_data + emis_row + [unit]
527
+
528
+ if len(activities) > 0:
529
+ source_activities = [
530
+ Activity.objects.get(id=sa.activity_id).name
531
+ for sa in source.activities.all()
532
+ ]
533
+ source_activity_rates = dict()
534
+ for act in source.activities.all():
535
+ activity_unit = Activity.objects.get(id=act.activity_id).unit
536
+ activity_rate = activity_rate_unit_from_si(act.rate, activity_unit)
537
+ source_activity_rates[
538
+ Activity.objects.get(id=act.activity_id).name
539
+ ] = activity_rate
540
+ act_row = [
541
+ source_activity_rates[name] if name in source_activities else 0
542
+ for name in activity_names
543
+ ]
544
+ row_data = row_data + act_row
545
+ worksheet.append(row_data)
546
+
547
+
548
+ def common_suffix(strings):
549
+ reversed_strings = [s[::-1] for s in strings]
550
+ common_suffix_reversed = os.path.commonprefix(reversed_strings)
551
+ return common_suffix_reversed[::-1]
@@ -0,0 +1,36 @@
1
+ from .codeset_import import import_activitycodesheet, import_codesetsheet # noqa
2
+ from .gridsource_import import import_gridsources # noqa
3
+ from .roadsource_import import ( # noqa
4
+ fleet_excel_to_dict,
5
+ import_congestion_profiles,
6
+ import_fleets,
7
+ import_roadclasses,
8
+ import_roads,
9
+ import_traffic,
10
+ import_vehicles,
11
+ roadclass_excel_to_dict,
12
+ roadsource_excel_to_dict,
13
+ vehicles_excel_to_dict,
14
+ )
15
+ from .source_import import import_sourceactivities, import_sources # noqa
16
+ from .timevar_import import import_timevars, import_timevarsheet # noqa
17
+
18
+ SHEETS = (
19
+ "CodeSet",
20
+ "ActivityCode",
21
+ "Timevar",
22
+ "Activity",
23
+ "EmissionFactor",
24
+ "PointSource",
25
+ "AreaSource",
26
+ "GridSource",
27
+ "RoadSource",
28
+ "VehicleFuel",
29
+ "Fleet",
30
+ "CongestionProfile",
31
+ "FlowTimevar",
32
+ "ColdstartTimevar",
33
+ "RoadAttriute",
34
+ "TrafficSituation",
35
+ "VehicleEmissionFactor",
36
+ )