Lookup Table Example#

This example demonstrates how to convert a Routee Powertrain model into a lookup table format. Lookup tables are useful for fast energy consumption predictions across a predefined grid of operating conditions.

import routee.powertrain as pt
import numpy as np

Loading Models#

First, let's load a few different models to demonstrate lookup table generation. We'll use models with different feature sets to show the flexibility of the approach.

toyota_camry = pt.load_model("toyota/camry_ice/2016/rf_base_67ae9982/v1")
tesla_model3 = pt.load_model("tesla/model_3_bev/2022/rf_base_fe510e40/v1")
tesla_with_temp = pt.load_model("tesla/model_3_bev/2022/rf_steady_thermal_ab1db342/v1")
/opt/hostedtoolcache/Python/3.10.21/x64/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

Let's examine the available features and targets for each model.

print("Toyota Camry features:", toyota_camry.feature_names)
print("Toyota Camry targets:", toyota_camry.metadata.config.target.target_name_list)
print()
print("Tesla Model 3 features:", tesla_model3.feature_names)
print("Tesla Model 3 targets:", tesla_model3.metadata.config.target.target_name_list)
print()
print("Tesla with Temperature features:", tesla_with_temp.feature_names)
print(
    "Tesla with Temperature targets:",
    tesla_with_temp.metadata.config.target.target_name_list,
)
Toyota Camry features: ['speed_mph', 'distance_mi']
Toyota Camry targets: ['fuel_gge']

Tesla Model 3 features: ['speed_mph', 'grade_pct', 'distance_mi']
Tesla Model 3 targets: ['electric_kwh']

Tesla with Temperature features: ['speed_mph', 'grade_percent', 'ambient_temp_f']
Tesla with Temperature targets: ['kwh']

Single Feature Lookup Table#

Let's start with a simple single-feature lookup table using speed only. This creates a 1D lookup table showing how energy consumption varies with vehicle speed.

# Define feature parameters for speed-only lookup
speed_only_params = [
    {
        "feature_name": "speed_mph",
        "lower_bound": 5.0,
        "upper_bound": 80.0,
        "n_samples": 16,  # Every 5 mph from 5 to 80
    },
    # Every feature the model takes needs a range. Holding distance at a single
    # sample keeps this a one-dimensional sweep over speed.
    {
        "feature_name": "distance_mi",
        "lower_bound": 0.5,
        "upper_bound": 1.5,
        "n_samples": 1,
    },
]

# Generate lookup table for Toyota Camry
camry_speed_lookup = toyota_camry.to_lookup_table(
    feature_parameters=speed_only_params,
    energy_target="fuel_gge",  # Gallons of gasoline equivalent
)

print("Single feature lookup table (first 5 rows):")
print(camry_speed_lookup.head())
Single feature lookup table (first 5 rows):
   speed_mph  distance_mi  fuel_gge_per_distance_mi
0        5.0            1                  0.067427
1       10.0            1                  0.046740
2       15.0            1                  0.039036
3       20.0            1                  0.033705
4       25.0            1                  0.030481

Two Feature Lookup Table#

Now let's create a more comprehensive 2D lookup table using both speed and grade. This shows how energy consumption varies with both vehicle speed and road grade.

# Define feature parameters for speed and grade
speed_grade_params = [
    {
        "feature_name": "speed_mph",
        "lower_bound": 25.0,
        "upper_bound": 65.0,
        "n_samples": 9,  # Every 5 mph from 25 to 65
    },
    {
        "feature_name": "grade_pct",
        "lower_bound": -6.0,
        "upper_bound": 6.0,
        "n_samples": 7,  # Every 2% grade from -6% to +6%
    },
    {
        "feature_name": "distance_mi",
        "lower_bound": 0.5,
        "upper_bound": 1.5,
        "n_samples": 1,
    },
]

# Generate lookup table for Tesla Model 3
tesla_speed_grade_lookup = tesla_model3.to_lookup_table(
    feature_parameters=speed_grade_params,
    energy_target="electric_kwh",
)

print(f"Two feature lookup table shape: {tesla_speed_grade_lookup.shape}")
print("Sample rows:")
print(tesla_speed_grade_lookup.head(10))
Two feature lookup table shape: (63, 4)
Sample rows:
   speed_mph  grade_pct  distance_mi  electric_kwh_per_distance_mi
0       25.0       -6.0            1                     -0.185075
1       30.0       -6.0            1                     -0.185075
2       35.0       -6.0            1                     -0.185075
3       40.0       -6.0            1                     -0.185075
4       45.0       -6.0            1                     -0.185075
5       50.0       -6.0            1                     -0.185075
6       55.0       -6.0            1                     -0.185075
7       60.0       -6.0            1                     -0.185075
8       65.0       -6.0            1                     -0.185075
9       25.0       -4.0            1                     -0.056483

Three Feature Lookup Table with Temperature#

For models that include temperature, we can create a 3D lookup table. This is particularly useful for electric vehicles where temperature significantly affects range.

# Define feature parameters including temperature
temp_params = [
    {
        "feature_name": "speed_mph",
        "lower_bound": 35.0,
        "upper_bound": 55.0,
        "n_samples": 3,  # 35, 45, 55 mph
    },
    {
        "feature_name": "grade_percent",
        "lower_bound": -2.0,
        "upper_bound": 4.0,
        "n_samples": 4,  # -2%, 0%, 2%, 4%
    },
    {
        "feature_name": "ambient_temp_f",
        "lower_bound": 20.0,
        "upper_bound": 80.0,
        "n_samples": 4,  # 20°F, 40°F, 60°F, 80°F
    },
]

# Generate lookup table with temperature
tesla_temp_lookup = tesla_with_temp.to_lookup_table(
    feature_parameters=temp_params,
    energy_target="kwh",
)

print(f"Three feature lookup table shape: {tesla_temp_lookup.shape}")
print("Sample rows showing temperature effects:")
print(tesla_temp_lookup.head(12))
Three feature lookup table shape: (48, 4)
Sample rows showing temperature effects:
    speed_mph  grade_percent  ambient_temp_f  kwh_per_distance
0        35.0           -2.0            20.0          0.124237
1        35.0           -2.0            40.0          0.063225
2        35.0           -2.0            60.0          0.063225
3        35.0           -2.0            80.0          0.063225
4        45.0           -2.0            20.0          0.124237
5        45.0           -2.0            40.0          0.063225
6        45.0           -2.0            60.0          0.063225
7        45.0           -2.0            80.0          0.063225
8        55.0           -2.0            20.0          0.124237
9        55.0           -2.0            40.0          0.063225
10       55.0           -2.0            60.0          0.063225
11       55.0           -2.0            80.0          0.063225
/opt/hostedtoolcache/Python/3.10.21/x64/lib/python3.10/site-packages/routee/powertrain/validation/physics.py:1088: UserWarning: '2022_Tesla_Model_3_RWD_0F_110F_steady trained July 2025' has no vehicle mass (mass_lbs), so its physical energy bounds cannot be computed and the output guardrail will not be applied to its predictions. Set mass_lbs on the model config to enable the guardrail. 
  warnings.warn(

Practical Usage: Interpolation for Route Prediction#

Lookup tables can be used for fast interpolation to predict energy consumption for specific driving conditions. Here's how you might use a lookup table for route prediction:

# Example: Using lookup table for fast prediction
def interpolate_energy_from_lookup(lookup_table, speed, grade=None, temp=None):
    if grade is None and temp is None:
        # 1D interpolation for speed only
        return np.interp(speed, lookup_table["speed_mph"], lookup_table.iloc[:, -1])
    else:
        # For multi-dimensional interpolation, you'd typically use scipy.interpolate
        # This is a simplified example
        closest_row = lookup_table.iloc[
            (lookup_table["speed_mph"] - speed).abs().argsort()[:1]
        ]
        return closest_row.iloc[0, -1]


# Example usage
example_speed = 42.5
predicted_energy = interpolate_energy_from_lookup(camry_speed_lookup, example_speed)
print(
    f"Interpolated energy consumption at {example_speed} mph: {predicted_energy:.4f} gge/mile"
)
Interpolated energy consumption at 42.5 mph: 0.0257 gge/mile

Best Practices and Considerations#

When creating lookup tables, consider:

  1. Resolution vs. Size: More samples mean higher accuracy but larger tables

  2. Feature Ranges: Ensure your lookup table covers the expected operating conditions

  3. Interpolation: For values between grid points, you'll need interpolation

  4. Memory Usage: Large multi-dimensional tables can consume significant memory

  5. Update Frequency: Lookup tables are static - update them when models change

Use Cases#

Lookup tables are particularly useful for:

  • Real-time applications requiring fast predictions

  • Embedded systems with limited computational resources

  • Integration with external systems that can't run Python models directly