Writing Custom Metrics for Pydre
Custom metrics in Pydre allow you to extract meaningful data from driving simulation data. Here's how to create one:
Basic Metric Structure
A custom metric is a function decorated with @registerMetric()
that takes a DriveData
object as its first parameter and returns a numeric value or collection of values.
from pydre.metrics import registerMetric
import pydre.core
@registerMetric()
def myCustomMetric(drivedata: pydre.core.DriveData, param1: str = "default") -> float:
"""Brief description of what this metric calculates
Parameters:
param1: Description of this parameter
Note: Requires data columns
- Column1: Description of required column
- Column2: Description of another required column
Returns:
Description of return value
"""
# Check for required columns
required_cols = ["Column1", "Column2"]
drivedata.checkColumns(required_cols)
# Verify columns are numeric
try:
drivedata.checkColumnsNumeric(required_cols)
except pydre.core.ColumnsMatchError:
return None
# Process data and compute the metric value
result = some_calculation(drivedata.data)
return result
Advanced Metrics
Multiple Return Values
For metrics that return multiple values, specify column names in the decorator:
@registerMetric(columnnames=["value1", "value2"])
def multiValueMetric(drivedata: pydre.core.DriveData) -> list[float]:
# ...
return [value1, value2]
Custom Metric Names
Override the function name for metric registration:
@registerMetric(metricname="betterMetricName")
def internal_function_name(drivedata: pydre.core.DriveData) -> float:
# ...
Best Practices
- Always validate required columns exist before processing
- Use robust error handling with clear log messages
- Return
None
when calculation fails rather than raising exceptions - Include comprehensive docstrings with parameter descriptions
- Use polars operations when possible for performance
Step-by-Step Guide
1. Create a Custom Metrics Directory
Create a directory for your custom metrics (outside the Pydre repository):
my_project/
├── custom_metric/
│ └── custom.py
├── data/
│ └── drive_data.dat
└── custom_test.toml
2. Set up your directory to use pydre
cd my_project
rye add pydre
rye sync
This will initialize the directory like a python package using rye and the pydre package. This will use the latest published version of pydre from PyPI. If you want to use the latest development version of pydre, you can clone the repository and add it as a dependency instead.
3. Write Your Custom Metrics
Create a Python file (e.g., custom.py
) in your custom metrics directory. Your metrics should use the @registerMetric()
decorator:
from typing import Optional
import polars as pl
import pydre.core
from pydre.core import ColumnsMatchError
from pydre.metrics import registerMetric
from loguru import logger
@registerMetric()
def testMean(
drivedata: pydre.core.DriveData, var: str, cutoff: Optional[float] = None
) -> Optional[float]:
try:
drivedata.checkColumnsNumeric([var])
except ColumnsMatchError:
return None
if cutoff is not None:
return (
drivedata.data.get_column(var)
.filter(drivedata.data.get_column(var) >= cutoff)
.mean()
)
else:
return drivedata.data.get_column(var).mean()
4. Configure Your Project File
Include your custom metrics directory in the config section of your project file.
[config]
custom_metrics_dirs = ["custom_metric"]
[metrics.custom_test]
function = "testMean"
var = "XPos"
4. Run Pydre with Your Custom Metrics
Run Pydre with your project file:
rye run pydre -p examples/custom_project/custom_test.toml -d examples/custom_project/data/Experimenter_S1_Tutorial_11002233.dat -o custom.csv
How It Works
- Pydre loads all metrics defined in its core library
- It then searches the directory paths specified in
custom_metrics_dirs
- For each Python file in those directories, it dynamically imports the metrics
- The
@registerMetric()
decorator automatically registers your custom metrics with pydre - Your metrics become available for use in the project configuration
Tips
- Ensure your custom metrics follow the same pattern as built-in metrics
- Add proper docstrings to document required columns and return values
- Always include error handling for missing columns using
checkColumns
orcheckColumnsNumeric
- Use type hints to document your function parameters and return values
With this approach, you can maintain your custom metrics separately from the Pydre codebase while still using them in your projects.
Custom filters
Custom filters can be created in a similar way to custom metrics. the search path for custom filters is similar to the custom metrics search path: "custom_filters_dirs". Additionally, @registerFilter()
instead of @registerMetric()
is used as the decorator.
Example
[config]
datafiles = ["data/drive_data.dat"]
outputfile = "results.csv"
custom_metrics_dirs = ["custom_metrics"]
custom_filters_dirs = ["custom_filters"]