PVRADAR is a framework for modelling without limits - flexible, transparent and seamless.

Back to Homepage https://pvradar.com/

Getting Started

Installation Instructions

Resource DB

Webinars and Examples

Core Concepts

Resources & R-Notation

Modeling Contexts

Docs under construction

Defining a Model (Chain)

Model parameter optimization

Satellite Databases and Meteo Stations

Adding a Technical Design

Table of Contents

Why PVRADAR?

<aside> đź’ˇ

The first core idea behind the PVRADAR Python package is simple: focus on your model logic, not on fetching and formatting input data.

</aside>

Let’s say you’ve defined a custom soiling model like this:

def my_soiling_model(rainfall, pm2_5, pm10, cleaning_threshold, ...):
    ...

Using PVRADAR, running ANY model requires just one line:

site.run(my_soiling_model)

The magic here is that site — the modeling context — **** automatically binds the required inputs to your function, meaning it retrieves the right data, applies unit conversions and aggregations, all according to user-defined preferences. You don’t need to worry about how the data gets from the satellite database or measurement station into your model. PVRADAR handles it.


<aside> đź’ˇ

The second core idea behind the PVRADAR Python package is to allow users to build flexible modeling workflows and digital twins — by seamlessly chaining together custom and prebuilt models (e.g., from pvlib) and embedding them in broader energy simulation contexts.

</aside>

You can rely on existing models where they make sense and intervene with your own custom logic where needed.

âś… Absolute Control. âś… Maximum Flexibility. âś… Full Transparency.


Key concepts

models

A model is a Python function that calculates results from a set of parameters. These parameters can be:

Example: a soiling model might calculate soiling loss based on rainfall, dust concentration and a cleaning threshold.


context

A context is an object that holds data (called resources) and metadata to be used by one or more models.

Examples:


resources

A resource is any data (e.g., time-series) registered in a context to serve as input to a model.

Each resource is linked to a specific resource type, which defines the physical meaning (e.g., rainfall) independently of unit, frequency, or source.

By adding a resource to a modeling context once, you ensure consistency across all models that use it.

➡️


Example: running a soiling model

Let’s walk through a concrete example — running the HSU model from pvlib for a random location in the USA.


Step 1: Define a modeling context

First, define a PvradarSite, which stores the location and modeling interval.

from pvradar.sdk import PvradarSite
site = PvradarSite(location=(33.074, -112.243), interval='2015..2016')

In this example the modeling context is a site in Arizona and any modeling will be done for the time between the first hour of 2015 and the last hour of 2016, in local time.

➡️ More on Modeling Contexts


Step 2: Retrieve input data (resources)

Now that the context is defined, fetching relevant data is very simple - in a single line of code!

rainfall = site.resource(R.rainfall) # returns total hourly rainfall in mm
pm2_5 = site.resource(R.pm2_5_volume_concentration) # mean hourly pm2.5 volume concentration in Kg/m^3
pm10 = site.resource(R.pm10_volume_concentration) # mean hourly pm10 volume concentration in Kg/m^3

Each R.xxx() is a resource descriptor, allowing you to “describe” what exactly you need:

Example with custom descriptors:

rainfall = site.resource(R.rainfall(data_source='merra2', to_unit='cm', to_freq='D'))
pm2_5 = site.resource(R.pm2_5_volume_concentration(to_unit='g/m^3', to_freq='D'))
pm10 = site.resource(R.pm10_volume_concentration(to_unit='g/m^3', to_freq='D'

Not sure what data exactly you are looking at? Use describe to print a short description.

from pvradar.sdk import describe
describe(rainfall)

rainfall: total daily rainfall in cm from merra2 731 data points (2015-01-01 00:00:00-05:00 to 2016-12-31 00:00:00-05:00)

➡️ More on Resources & R-Notation

➡️ See the list of available data sources for each resource type in


Step 3: Run the model

Finally, run the HSU soiling model from pvlib:

from pvlib.soiling import hsu
soiling_hsu = hsu(rainfall, 1, 25, pm2_5, pm10) # cleaning threshold = 1 mm, tilt = 25 deg

Done! You now have soiling loss factors from the HSU model for your location and interval.

But there’s a better way...

Example: modeling grid energy with and without soiling

Let’s say we want to use the HSU model as one part of a larger model network to estimate energy delivered to the grid — both with and without soiling losses.


Step 1: Wrap the HSU model

The first thing we need to do is bring the model into a from that is compatible with PVRADAR. This means:

@resource_type(R.soiling_loss_factor(set_unit='fraction'))
def my_soiling_model_based_on_hsu(
    *,
    pm2_5: Annotated[pd.Series, R.pm2_5_volume_concentration(to_unit='g/m^3')],
    pm10: Annotated[pd.Series, R.pm10_volume_concentration(to_unit='g/m^3')],
    rainfall: Annotated[pd.Series, R.rainfall(to_unit='mm')],
    cleaning_threshold: float = 1,
    tilt: float,
) -> pd.Series:

    soiling_ratio = hsu(
        rainfall=rainfall,
        cleaning_threshold=cleaning_threshold,
        surface_tilt=tilt,
        pm2_5=pm2_5,
        pm10=pm10,
    )

    return 1 - soiling_ratio