Skip to main content

Framework for developing synthetic distribution feeder model.

Project description

TestsPR TestsDocsPublishPyPI DownloadsLicenseIssuesCodeFactorCodecovMCP ServerMCP Tools

NREL-shift

A Python framework for building synthetic power distribution feeder models from open-source geospatial data. NREL-shift fetches building parcels and road networks from OpenStreetMap, constructs graph-based network topologies, and exports simulator-ready models through Grid Data Models and Ditto.

Features

  • Automated Feeder Generation — Build distribution feeder models directly from OpenStreetMap data
  • Graph-Based Network Modeling — Represent distribution networks as NetworkX graphs with typed nodes and edges
  • Equipment Mapping — Assign transformers, loads, and other equipment to network components
  • Phase Balancing — Automatically balance phases across distribution transformers
  • Voltage Mapping — Assign voltage levels throughout the distribution network based on transformer topology
  • Visualization — Built-in Plotly-based plotting for parcels, networks, and phase/voltage overlays
  • Simulator Export — Write models to OpenDSS, CYME, Synergi, and other simulators via Grid Data Models

Installation

From PyPI

pip install nrel-shift

From Source

git clone https://github.com/NLR-Distribution-Suite/shift.git
cd shift
pip install -e .

Optional Extras

# Development (testing + linting)
pip install -e ".[dev]"

# Documentation
pip install -e ".[doc]"

# MCP server (AI agent integration)
pip install -e ".[mcp]"

# Everything
pip install -e ".[dev,doc,mcp]"

Quick Start

The typical workflow has four stages: fetch data → build graph → configure mappers → build system.

1. Fetch Parcels and Road Network

from shift import parcels_from_location, get_road_network, GeoLocation
from gdm.quantities import Distance

# Fetch building parcels from OpenStreetMap
parcels = parcels_from_location("Fort Worth, TX", Distance(500, "m"))

# Fetch the road network for the same area
road_network = get_road_network("Fort Worth, TX", Distance(500, "m"))

You can also pass coordinates instead of an address:

location = GeoLocation(longitude=-97.3, latitude=32.75)
parcels = parcels_from_location(location, Distance(500, "m"))

2. Build a Distribution Graph

from shift import get_kmeans_clusters, PRSG, GeoLocation

# Cluster parcels for transformer placement (~2 customers per transformer)
parcel_points = [
    p.geometry[0] if isinstance(p.geometry, list) else p.geometry
    for p in parcels
]
clusters = get_kmeans_clusters(max(len(parcels) // 2, 1), parcel_points)

# Build the distribution graph from clusters and road network
builder = PRSG(
    groups=clusters,
    source_location=GeoLocation(-97.3, 32.75),
)
graph = builder.get_distribution_graph()

3. Configure Mappers and Build the System

from shift import (
    BalancedPhaseMapper,
    TransformerVoltageMapper,
    EdgeEquipmentMapper,
    DistributionSystemBuilder,
    TransformerPhaseMapperModel,
    TransformerVoltageModel,
    TransformerTypes,
)
from gdm import DistributionTransformer
from gdm.quantities import ApparentPower, Voltage

# Phase mapper — assign phases to transformer secondaries
transformer_phase_models = [
    TransformerPhaseMapperModel(
        tr_name=edge.name,
        tr_type=TransformerTypes.SPLIT_PHASE,
        tr_capacity=ApparentPower(25, "kilovoltampere"),
        location=graph.get_node(from_node).location,
    )
    for from_node, _, edge in graph.get_edges()
    if edge.edge_type is DistributionTransformer
]
phase_mapper = BalancedPhaseMapper(graph, mapper=transformer_phase_models, method="agglomerative")

# Voltage mapper — assign primary/secondary voltages
voltage_mapper = TransformerVoltageMapper(
    graph,
    xfmr_voltage=[
        TransformerVoltageModel(
            name=edge.name,
            voltages=[Voltage(7.2, "kilovolt"), Voltage(120, "volt")],
        )
        for _, _, edge in graph.get_edges()
        if edge.edge_type is DistributionTransformer
    ],
)

# Build the system
from pathlib import Path
from gdm import DistributionSystem
import shift

MODELS_FOLDER = Path(shift.__file__).parent.parent.parent / "tests" / "models"
catalog_sys = DistributionSystem.from_json(MODELS_FOLDER / "p1rhs7_1247.json")

system = DistributionSystemBuilder(
    name="fort_worth_feeder",
    dist_graph=graph,
    phase_mapper=phase_mapper,
    voltage_mapper=voltage_mapper,
    equipment_mapper=EdgeEquipmentMapper(graph, catalog_sys, voltage_mapper, phase_mapper),
)
distribution_system = system.get_system()

See the Complete Example for a full end-to-end walkthrough.

Documentation

User Guides

These guides walk through individual stages of the workflow:

Guide Description
Complete Example End-to-end workflow from data fetching to system export
Fetching Parcels Loading building parcels from CSV, addresses, or GeoDataFrames
Building a Graph Constructing distribution graphs from clustered parcels
Updating Branch Types Changing edge types for specific equipment models
Mapping Phases Assigning phases with balanced or custom mappers
Mapping Voltages Assigning voltage levels via transformer topology
Mapping Equipment Mapping loads, sources, and catalog equipment
Building a System Assembling the final distribution system model

MCP Server (AI Agent Integration)

NREL-shift includes an MCP server for use with LLM-based agents. See the MCP Server Guide for setup and usage.

Developer Resources

Running Tests

pip install -e ".[dev]"

pytest                              # Run all tests
pytest --cov=shift --cov-report=html  # With coverage report
pytest tests/test_graph.py          # Single test file
pytest -m "not slow"                # Skip slow tests

Requirements

License

BSD-3-Clause — see LICENSE.txt.

Authors

Citation

@software{nrel_shift,
  title = {NREL-shift: Framework for Developing Synthetic Distribution Feeder Models},
  author = {Duwadi, Kapil and Latif, Aadil and Pohl, Erik},
  year = {2026},
  url = {https://github.com/NLR-Distribution-Suite/shift}
}

Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nrel_shift-0.6.3.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nrel_shift-0.6.3-py3-none-any.whl (72.4 kB view details)

Uploaded Python 3

File details

Details for the file nrel_shift-0.6.3.tar.gz.

File metadata

  • Download URL: nrel_shift-0.6.3.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nrel_shift-0.6.3.tar.gz
Algorithm Hash digest
SHA256 6b54d3edfb014a27a67be65ca05f27253ad80dd09dc67e50c6b8e5f2f36ec5f1
MD5 d01ce13758804aa1c9221757a4533c22
BLAKE2b-256 9a783e2e016b6379e4d1a96980a57fa9d2d20e0494ec6118a83980ba0d776cbd

See more details on using hashes here.

Provenance

The following attestation bundles were made for nrel_shift-0.6.3.tar.gz:

Publisher: publish_to_pypi.yaml on NLR-Distribution-Suite/shift

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nrel_shift-0.6.3-py3-none-any.whl.

File metadata

  • Download URL: nrel_shift-0.6.3-py3-none-any.whl
  • Upload date:
  • Size: 72.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nrel_shift-0.6.3-py3-none-any.whl
Algorithm Hash digest
SHA256 d6e68e61e5671888fc74ba9086e65650e3961046ea2b46c32332422127180301
MD5 a25ffd7281725b4f68ebc7aaf734f268
BLAKE2b-256 34a68a2d12666be1d024780b8bef52e7ca70ec1e3ac924a9aef5f27a48d07972

See more details on using hashes here.

Provenance

The following attestation bundles were made for nrel_shift-0.6.3-py3-none-any.whl:

Publisher: publish_to_pypi.yaml on NLR-Distribution-Suite/shift

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page