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

Core Concepts

Resources & R-Notation

Modeling Contexts

Timestamp alignment & resampling

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.

➡️ Resource DB


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 Resource DB


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