DOI: 10.5281/zenodo.17941137
title: Data-driven Energy and Power Demand Estimation for Electric Freight Transport in Finland – Data Repository

description: This repository accompanies the study “Data-driven Energy and Power Demand Estimation for Electric Freight Transport in Finland” and provides the key data and code used to estimate spatially and temporally resolved energy demand for heavy-duty road transport in Finland.

The workflow links:





network-level segment data with energy intensities and traffic volumes,




synthetic long-distance freight routes between municipalities,




temporal traffic profiles (hourly and weekday factors), and




simple operational factors (temperature, payload),



to produce consistent estimates of electric freight energy and power demand at the road-segment and grid-cell level.

Repository contents

The Zenodo deposit contains four core files:





energy_fleet_factors.csv




routes.csv




Temporal_factors_for_Finnish_roads_processed.csv




assemble_factors.py



Below we describe each file, its role in the study, and how it fits into the overall workflow.

File 1: energy_fleet_factors.csv

Purpose

energy_fleet_factors.csv stores road-segment-level energy intensity and fleet composition for heavy-duty vehicles. It is the main static input for the temporal scaling step, where energy demand is computed for specific months, days, and hours.

Each row corresponds to a road segment identified by a unique oid and a WKT geometry.

Main columns

For each segment:





oidUnique identifier of the road segment (from the underlying Finnish road network data).




geometry_wktSegment geometry in WKT format, typically LINESTRING in a projected CRS compatible with ETRS-TM35FIN.




Per-vehicle-type SOC and energy intensity:





Semi-Trailer_SOC, Semi-Trailer_ReqEnergy




Truck-with-trailer_SOC, Truck-with-trailer_ReqEnergy




Truck-w/o-trailer_SOC, Truck-w/o-trailer_ReqEnergy




Bus_SOC, Bus_ReqEnergy



Here:





*_SOC represents a typical state of charge (%) for that vehicle type on the segment, based on prediction outputs (WeTRaC).




*_ReqEnergy represents a per-vehicle energy requirement for traversing the segment (energy intensity). In the temporal step, these values are scaled by vehicle counts and operational factors (temperature, payload) to obtain total energy consumption.






Total heavy-vehicle volume:





VolumeAggregate heavy-vehicle volume assigned to the segment (same unit as in the original traffic count data; typically vehicles per day).






Fleet fractions (vehicle-type shares of total volume):





Semi-Trailer_frac




Truck-with-trailer_frac




Truck-w/o-trailer_frac




Bus_frac



These represent the fraction of Volume attributed to each vehicle type:
Volumetype=Volume×type_frac


Length-based re-weighting of fleet fractions

The fleet fractions in energy_fleet_factors.csv are not purely local counts. Instead, they are re-weighted using route-length information derived from the synthetic routes:





Synthetic routes between municipality pairs (see routes.csv) are assigned to three length bins:





<50  routes shorter than 50 km




50-300 routes between 50 km and 300 km (inclusive)




>300 routes longer than 300 km






For each route-length bin, a conditional vehicle-type composition P(type∣length bin) is assumed, reflecting that:





short routes (<50 km) tend to involve more buses and shorter rigid trucks,




medium routes (50–300 km) have a more mixed fleet, and




long routes (>300 km) are dominated by articulated heavy trucks.






Volumes in the original route files are redistributed proportionally to P(type∣length bin) and aggregated back to the segment level to obtain the final Volume and *_frac values in energy_fleet_factors.csv.



The exact numerical weights are defined explicitly in the code (p_type_given_bin in assemble_factors.py), so they are fully transparent and reproducible.

File 2: routes.csv

Purpose

routes.csv contains route-level geometries and lengths for the synthetic freight routes used in the study. Each row represents a single origin–destination (OD) route between two municipalities (or sub-areas), assembled from individual road segments.

These routes serve two main purposes:





They describe typical long-distance freight paths across the Finnish road network.




Their lengths are used to classify OD relations into length bins (<50, 50–300, >300 km), which then drive the length-dependent fleet composition used in energy_fleet_factors.csv.



Columns

For each route:





route_idUnique text identifier of the route, typically combining origin, destination, and an internal index, e.g.:





JyvÃ¤skylÃ¤_Ã„Ã¤nekoski_0-14365




Vantaa_Vantaa_0-33023



Note: some municipality names may appear with UTF-8 mojibake (e.g. JyvÃ¤skylÃ¤), but the processing uses a canonicalized version of route_id internally, so this does not affect the results.




route_geometry_wktAssembled route geometry in WKT format:





Usually LINESTRING for a continuous route,




Sometimes MULTILINESTRING if the assembly process retains multiple connected parts.



The geometry is in the same projected CRS as the segment data (ETRS-TM35FIN-compatible).




route_length_mTotal route length in metres, computed from the assembled geometry.




route_length_kmTotal route length in kilometres, defined as
route_length_km=route_length_m / 1000



route_length_categoryCategorical route-length class:





<50  route shorter than 50 km




50-300 route between 50 km and 300 km (inclusive)




>300 route longer than 300 km



This field links route-level information to the length-dependent fleet composition P(type∣bin) used when computing vehicle-type fractions in energy_fleet_factors.csv.



How routes.csv was generated

routes.csv is produced from per-route segment CSVs by:





Merging segment geometries per route using the function assemble_routes() in assemble_factors.py.




Computing geometric lengths in metres and converting to kilometres.




Assigning each route to one of the three length categories based on route_length_km.



This file is included so that users can:





Inspect the spatial layout of synthetic OD routes, and




Understand and, if needed, reproduce or adjust the length-based fleet composition logic.



File 3: Temporal_factors_for_Finnish_roads_processed.csv

Purpose

Temporal_factors_for_Finnish_roads_processed.csv provides time-of-week traffic scaling factors for each road segment. It captures:





weekday-specific variation (Monday–Sunday), and




hour-of-day variation (0–23 hours),



and is used together with energy_fleet_factors.csv in combine_energy_temporal() to obtain scenario-specific vehicle counts and energy demand.

Each row corresponds to a road segment identified by oid, consistent with energy_fleet_factors.csv.

Columns

For each segment:





oidRoad-segment identifier, matching the oid used in energy_fleet_factors.csv.




Weekday factors (dimensionless multipliers, typically around 1):





weekday_factor_ma – Monday (ma)




weekday_factor_ti – Tuesday (ti)




weekday_factor_ke – Wednesday (ke)




weekday_factor_to – Thursday (to)




weekday_factor_pe – Friday (pe)




weekday_factor_la – Saturday (la)




weekday_factor_su – Sunday (su)



These values represent relative traffic intensity by weekday for the segment. In combine_energy_temporal(), subsets of these columns are averaged depending on the selected weekdays (or all are averaged if no selection is made) to form a weekday multiplier.




Hourly factors (dimensionless multipliers, indexed 0–23):





hour_0, hour_1, …, hour_23



These values represent relative traffic intensity by hour of day for the segment. In combine_energy_temporal():





A subset of hours (or all 24 hours) is selected.




The corresponding hour_* values are averaged to yield an hourly multiplier.




If daily_average=True, this hourly multiplier is scaled to a daily equivalent within the function.





The exact normalization (e.g. whether the hourly factors sum to a constant) follows the preprocessing implemented in the script; users interested in the precise scaling can inspect the comments and operations in assemble_factors.py.

Role in the workflow

In combine_energy_temporal():





energy_fleet_factors.csv and Temporal_factors_for_Finnish_roads_processed.csv are merged by oid.




A weekday multiplier is computed from the weekday_factor_* columns, based on the selected weekdays.




An hourly multiplier is computed from the hour_* columns, based on the selected hours.




These are combined with monthly factors (derived from a global weekly profile) to form an overall temporal multiplier that scales the base Volume per segment to the selected time window.



The temporal factors are provided in this pre-processed CSV form to avoid re-running the cleaning, conversion, and scaling steps from the original Excel source.

File 4: assemble_factors.py

Purpose

assemble_factors.py contains the main processing logic used in the study. It connects:





the segment-level energy and fleet data (energy_fleet_factors.csv),




the route-level length information (consistent with routes.csv),




temporal traffic profiles (Temporal_factors_for_Finnish_roads_processed.csv), and




simple operational factors (temperature, payload),



to produce scenario-specific energy demand at segment level and, optionally, aggregated to a regular grid.

Main components

Key functions and components in the script:





compute_monthly_factors(weekly_factors)Aggregates 52 weekly scaling factors into 12 monthly factors, used as seasonal multipliers.




Helpers for encoding and route ID handling:





fix_mojibake(s)




canonical_route_key(s)Used to robustly match route IDs between different files even when encoding issues appear.






get_energy_fleet_factors(energy_dir, routes_dir, route_lengths_path, chunksize)(Optional for typical users; the repository already includes energy_fleet_factors.csv.)





Reads detailed per-route energy outputs and fleet volumes from input directories.




Uses route lengths and length bins to apply the conditional fleet composition P(type∣bin).




Aggregates data to the road-segment level to compute:





average SOC and energy intensity (*_SOC, *_ReqEnergy),




total Volume, and




fleet fractions (*_frac).






Writes the resulting segment-level table to energy_fleet_factors.csv.






assemble_routes(routes_dir='routes_csv/', output_file='assembled_routes.csv', simplify=False, simplify_tol=0.001)





Merges per-route segment CSVs into a route-level file with





route_id and




route_geometry_wkt.






This function was used to generate the geometries that underpin routes.csv (length computation and length-category assignment).






calculate_payload_factor(payload)





Encodes a simple linear payload effect on energy consumption, normalised so that a reference gross vehicle weight (GVW) yields a factor of 1.






calculate_temperature_energy(gvw, temperature) andcalculate_temperature_factor(gvw, temperature)





Implement piecewise-linear temperature-dependent energy factors, normalised such that a reference vehicle at 0 °C has factor 1.




Used to adjust per-segment energy consumption in combine_energy_temporal().






generate_time_label(selected_months, selected_weekdays, selected_hours, temperature, gvw, daily_average)





Builds descriptive output filenames encoding the temporal and operational scenario.






combine_energy_temporal(...)This is the main function used to generate scenario-specific demand files:





Inputs:





energy_csv: typically energy_fleet_factors.csv.




temporal_csv: typically Temporal_factors_for_Finnish_roads_processed.csv.




Temporal selections: selected_months, selected_weekdays, selected_hours.




Operating conditions: temperature, gvw (per type), daily_average.




Optional: resolution_km to aggregate results into a regular grid.






Steps:





Computes a temporal multiplier combining monthly, weekday, and hourly factors.




Multiplies segment Volume by this multiplier to obtain the number of vehicles in the selected scenario.




Splits vehicles into types using the fleet fractions (*_frac) and computes per-type vehicle counts.




Applies temperature and payload factors to scale the per-vehicle energy intensities (*_ReqEnergy) and obtains total energy per segment and vehicle type.




Optionally aggregates segment results into grid cells of size resolution_km (summing energy and volumes, averaging SOC).






Output: a CSV named according to the scenario (e.g. energy_M-All_W-All_H-All_T-...csv), containing segment-level (and, if requested, grid-level) energy demand and volumes.






Main block (if __name__ == "__main__":)





Provides an example workflow:





If Temporal_factors_for_Finnish_roads_processed.csv exists, it calls combine_energy_temporal() with default selections.




Otherwise, it reads an Excel file of temporal factors, cleans and converts it to Temporal_factors_for_Finnish_roads_processed.csv, which can then be used for temporal scaling.







How to set up and run the Python script (concise)

Requirements





Python ≥ 3.8




Recommended packages (install via pip install):





pandas




numpy




shapely





Example:







 



pip install pandas numpy shapely



Basic usage: temporal energy demand





Place the following files in the same working directory as assemble_factors.py:





energy_fleet_factors.csv




Temporal_factors_for_Finnish_roads_processed.csv






In assemble_factors.py, in the if __name__ == "__main__": block, adjust the parameters of combine_energy_temporal() if desired, e.g.:





selected_months: list of months (e.g. [1, 2, 12] for winter) or None for all months.




selected_weekdays: list of weekdays (e.g. ['ma','ti','ke','to','pe']) or None.




selected_hours: list of hours (0–23) or None.




temperature: explicit temperature in °C, or None to use a month-based average.




daily_average: if True, scales results to a daily total.




resolution_km: optional grid resolution (e.g. 10) for grid aggregation.






Run:









 



python assemble_factors.py







The script will output:





A segment-level CSV with energy and volumes (name derived from the scenario), and




If resolution_km is set, a grid-aggregated CSV (e.g. ..._grid-10km.csv).





Advanced usage: rebuilding energy_fleet_factors.csv (optional)

If you have the original per-route energy and volume CSVs:





Organise them in directories (e.g. energy_csv/, routes_csv/).




Provide a route-length file consistent with routes.csv (e.g. route_lengths.csv).




Call get_energy_fleet_factors(...) from Python to regenerate energy_fleet_factors.csv.



Most users will not need this step, as the repository already includes a ready-to-use energy_fleet_factors.csv.

Citation and reuse

When using this dataset or the associated code, please cite the corresponding scientific article and refer to this Zenodo record (including DOI). The data and code can be reused for:





national or regional freight electrification scenarios,




grid impact analyses, and




methodological benchmarking of transport energy models,



provided that appropriate credit is given and any domain-specific licensing conditions (e.g. for underlying road and traffic data) are respected.