Skip to content

Commit

Permalink
Improve docs
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-thom committed Feb 8, 2024
1 parent 38e2cba commit 036287f
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 11 deletions.
9 changes: 7 additions & 2 deletions docs/explanation/system.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Refer to the [System API](#system-api) for complete information.
Parent packages must choose one of the following:

1. Derive a custom System class that inherits from `infrasys.System`. Re-implement methods
as desired.
as desired. Add custom attributes to the System that will be serialized to JSON.

- Reimplement `System.add_components` in order to perform custom validation
or custom behavior. For example, a package may implement a load that
Expand All @@ -29,4 +29,9 @@ as desired.
2. Implement an independent System class and compose the `infrasys.System`. This can be beneficial
if you want to make the underlying system opaque to users.

3. Use `infrasys.System` directly. This is probably not what most users want.
- This pattern requires that you call `System.to_json()` with the keyword argument `data` set
to a dictionary containing your system's attributes. `infrasys` will add its contents to a
field called `system` inside that dictionary.

3. Use `infrasys.System` directly. This is probably not what most packages want because they will
not be able to serialize custom attributes or implement specialized behavior as discussed above.
36 changes: 31 additions & 5 deletions docs/explanation/time_series.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
# Time Series
Infrastructure systems supports time series data expressed as a one-dimensional array of floats.
Users must provide a `variable_name` that is typically the field of a component being modeled. For
example, if the user has a time array associated with the active power of a generator, they would assign
`variable_name = "active_power"`. Users can attach their own attributes to each time array. For example,
there might be different profiles for different model years.
Infrastructure systems supports time series data expressed as a one-dimensional array of floats
using the class [SingleTimeSeries](#singe-time-series-api). Users must provide a `variable_name`
that is typically the field of a component being modeled. For example, if the user has a time array
associated with the active power of a generator, they would assign
`variable_name = "active_power"`.

Here is an example of how to create an instance of `SingleTimeSeries`:

```python
import random
time_series = SingleTimeSeries.from_array(
data=[random.random() for x in range(24)],
variable_name="active_power",
initial_time=datetime(year=2030, month=1, day=1),
resolution=timedelta(hours=1),
)
```

Users can attach their own attributes to each time array. For example,
there might be different profiles for different scenarios or model years.

```python
time_series = SingleTimeSeries.from_array(
data=[random.random() for x in range(24)],
variable_name="active_power",
initial_time=datetime(year=2030, month=1, day=1),
resolution=timedelta(hours=1),
scenario="high",
model_year="2035",
)
```

## Behaviors
Users can customize time series behavior with these flags passed to the `System` constructor:
Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

This package implements a data store for components and time series in support of Python-based
modeling packages. While it is designed to support teams modeling transmission and distribution
systems, it can be used by any package that needs to store components (e.g., generators and buses)
that have quantities (e.g., power and voltage) which may vary over time.
systems for electrical grids, it can be used by any package that needs to store components (e.g.,
generators and buses) that have quantities (e.g., power and voltage) which may vary over time.

## Features
- Stores components in data structures that provide fast lookup and iteration by type and name.
Expand Down
9 changes: 9 additions & 0 deletions docs/reference/api/time_series.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@
.. autopydantic_model:: infrasys.time_series_models.TimeSeriesData
:members:
```

```{eval-rst}
.. _singe-time-series-api:
```

```{eval-rst}
.. autopydantic_model:: infrasys.time_series_models.SingleTimeSeries
:members:
```
39 changes: 37 additions & 2 deletions docs/tutorials/custom_system.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Custom System
This tutorial describes how to create a custom system in a parent package.
This tutorial describes how to create and use a custom system in a parent package.

1. Define the system. This example defines some custom attributes to illustrate serialization and
de-serialization behaviors.

```python
from typing import Any

from infrasys import System

class System(System):
class CustomSystem(System):
"""Custom System"""

def __init__(self, my_attribute=5, *args, **kwargs):
Expand All @@ -34,6 +36,7 @@ can handle format changes that might occur in the future.
2. Define some component classes.

```python
from uuid import UUID
from infrasys.component_models import ComponentWithQuantities
from infrasys.location import Location

Expand Down Expand Up @@ -85,3 +88,35 @@ what a component might look like in the REPL.
- The `Bus` class implements a custom check when it is added to the system. It raises an exception
if its `Location` object is not already attached to the system. The same could be done for
generators and buses.

3. Build a system.

```python
import random
from datetime import datetime, timedelta

from infrasys.location import Location
from infrasys.time_series_models import SingleTimeSeries

system = CustomSystem(name="my_system", my_attribute=10)
location = Location(x=0.0, y=0.0)
bus = Bus(name="bus1", voltage=1.1, coordinates=location)
gen = Generator(name="gen1", available=True, bus=bus, active_power=1.2, rating=1.1)
system.add_components(location, bus, gen)
time_series = SingleTimeSeries.from_array(
data=[random.random() for x in range(24)],
variable_name="active_power",
initial_time=datetime(year=2030, month=1, day=1),
resolution=timedelta(hours=1),
)
system.add_time_series(time_series, gen)
```

4. Serialize and de-serialize the system.

```python
system.to_json("system.json")
system2 = CustomSystem.from_json("system.json")
assert system.get_component(Generator, "gen1").active_power == \
system2.get_component(Generator, "gen1").active_power
```

0 comments on commit 036287f

Please sign in to comment.