Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manipulating datasets tutorial #1245

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft

Manipulating datasets tutorial #1245

wants to merge 10 commits into from

Conversation

kdayday
Copy link
Contributor

@kdayday kdayday commented Jan 7, 2025

Merged Anna's branch to NREL-Sienna/ branch

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit

JuliaFormatter

[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

Now using the [`set_base_voltage!`](@ref) function and a `for loop` we can update the voltage:


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

set_base_voltage!(i, 250.0)
end


[JuliaFormatter] reported by reviewdog 🐶

We can see that all of the buses now have a `base_voltage` of 250.0:


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

If we are interested in updating the `fuel` in all the thermal generators, we would use a similar approach. We begin by grabbing an iterator for all the components in [`ThermalStandard`](@ref).


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

Now, using the [`set_fuel!`](@ref) and a for loop, we will update the `fuel` to `NATURAL_GAS`.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

set_fuel!(i, ThermalFuels.NATURAL_GAS)


[JuliaFormatter] reported by reviewdog 🐶

We can see that the `fuel` types for all the thermal generators has been updated.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

We can also use a dot operator with a specific `get_*` function and the [`get_components`](@ref) function to return a vector of parameters for multiple components:
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

Notice that the `fuel` type for all the thermal generators is returned.


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

Using the "dot" access to get a parameter value from a component is actively discouraged, use `get_*` functions instead. Julia syntax enables access to this data using the "dot" access, however this is discouraged for two reasons:
1. We make no guarantees on the stability of component structure definitions. We will maintain version stability on the accessor methods.
2. Per-unit conversions are made in the return of data from the accessor functions. (see the [per-unit](https://nrel-sienna.github.io/PowerSystems.jl/stable/explanation/per_unit/#per_unit) section for more details)


[JuliaFormatter] reported by reviewdog 🐶

We have seen how to update a single component, and all the components of a specific type, but what if we are interested in updating particular components? We can do this using filter functions. For example, let's say we are interested in updating all the `active_power` parameters of the thermal generators except `Solitude`.
Let's start by seeing the current `active_power` parameters.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

Let's grab an iterator for the all the thermal generators except `Solitude` using a filter function:
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

We can see that four [`ThermalStandard`](@ref) components are returned. Now let's update the `active_power` parameter of these four thermal generators using the [`set_active_power!`](@ref) function.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

Let's check the update using [`show_components`](@ref):


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

We can see that all the `active_power` parameters are 0.0, except `Solitude`.


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

We can see that `Solitude` has a rating of 5.2 and `Alta` has a rating of 0.5.
```@repl system
thermal_rating = get_components(x -> get_rating(x) == 5.2 || get_rating(x) == 0.5, ThermalStandard, sys )


[JuliaFormatter] reported by reviewdog 🐶

We can see that two components are returned. If we wanted to update those ratings to 4.0:
```@repl system
for i in thermal_rating
set_rating!(i, 4.0)


[JuliaFormatter] reported by reviewdog 🐶

The rating parameters of `Solitude` and `Alta` are now 4.0:
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

The [`get_available_components`](@ref) function allows us to grab all the components of a particular type that are available. For example, if we are interested in grabbing all the available renewable generators:
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

The two [`RenewableDispatch`](@ref) components are returned because they are available.


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

Let's check the availability of our [`ThermalStandard`](@ref) components.


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

Recall that the default columns returned when using [`show_components`](@ref) are the name and availability.


[JuliaFormatter] reported by reviewdog 🐶

We can access the [`ACBus`](@ref), notice that we need define some basic data, including the bus's


[JuliaFormatter] reported by reviewdog 🐶

components in the system using the [`get_buses`](@ref) function. There are multiple approaches to using this function, but in this tutorial we are going to focus on getting buses using the ID numbers.


[JuliaFormatter] reported by reviewdog 🐶

components using the [`get_bus_numbers`](@ref) function.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

We can see that a vector of values 1:5 is returned. Now let's grab the buses using the [`get_buses`](@ref) function.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

The 5 buses in the system are returned.


[JuliaFormatter] reported by reviewdog 🐶

We can also access and update the component name parameter using the [`get_name`](@ref) and [set_name!](@ref) functions.
Recall that we created an iterator called `thermal_gens` for all the thermal generators. We can use the [`get_name`](@ref) function to access the `name` parameter for these components.


[JuliaFormatter] reported by reviewdog 🐶

for i in thermal_gens
@show get_name(i)


[JuliaFormatter] reported by reviewdog 🐶

To update the names we will use the [set_name!](@ref) function. However, it is important to note that using [set_name!](@ref) not only changes the field `name`, but also changes the container itself. Therefore, it is crucial to do the following:
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

set_name!(sys, thermal_gen, get_name(thermal_gen)*"-renamed")


[JuliaFormatter] reported by reviewdog 🐶

Now we can check the names using the [`get_name`](@ref) function again.
```@repl system
get_name.(get_components(ThermalStandard,sys))
```


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

So far we have seen that we can view different data types in our system using the `show_components` function, we can access those types using the `get_*` function, and we can manipulate them using the `set_*` functions.
Follow the next tutorials to learn how to [work with time series](https://nrel-sienna.github.io/PowerSystems.jl/stable/tutorials/working_with_time_series/).

Copy link

codecov bot commented Jan 7, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 84.30%. Comparing base (effc91c) to head (199900e).
Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1245   +/-   ##
=======================================
  Coverage   84.30%   84.30%           
=======================================
  Files         181      181           
  Lines        8409     8409           
=======================================
  Hits         7089     7089           
  Misses       1320     1320           
Flag Coverage Δ
unittests 84.30% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit

JuliaFormatter

[JuliaFormatter] reported by reviewdog 🐶

See that the pretty-print summarizes this set of components, but let's check what was actually returned:


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

Notice that `PowerSystems.jl` returns Julia iterators in order to avoid unnecessary memory allocations


[JuliaFormatter] reported by reviewdog 🐶

Use [`collect`](https://docs.julialang.org/en/v1/base/collections/#Base.collect-Tuple{Any})


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

set_base_voltage!(i, 250.0)
end


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

We can see that all of the buses now have a `base_voltage` of 250.0 kV.


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

Now, using the [`set_fuel!`](@ref set_fuel!(value::ThermalStandard)) and a `for` loop, we will update the `fuel` to `NATURAL_GAS`.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

set_fuel!(i, ThermalFuels.NATURAL_GAS)


[JuliaFormatter] reported by reviewdog 🐶

We can verify that the `fuel` types for all the thermal generators has been updated,


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

We have seen how to update a single component, and all the components of a specific type, but what if we are interested in updating only particular components? We can do this using filter functions. For example, let's say we are interested in updating all the `active_power` values of the thermal generators except `Solitude`.
Let's start by seeing the current `active_power` values.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

Let's grab an iterator for the all the thermal generators except `Solitude` by adding a filter function


[JuliaFormatter] reported by reviewdog 🐶

filter_func::Function,
::Type{T},
sys::System;
subsystem_name = nothing,


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

We can see that four [`ThermalStandard`](@ref) components are returned. Now let's update the `active_power` field of these four thermal generators using the [`set_active_power!`](@ref) function.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

Let's check the update using [`show_components`](@ref):


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

We can see that all the `active_power` values are 0.0, except `Solitude`.


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

The [`get_available_components`](@ref) function is a useful short-hand function with a


[JuliaFormatter] reported by reviewdog 🐶

For example, if we are interested in grabbing all the available [`ThermalStandard`](@ref):
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

We only retrieved one component, because the rest have been set to unavailable:
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

We can retrieve the [`ACBus`](@ref) components using


[JuliaFormatter] reported by reviewdog 🐶

components using the [`get_bus_numbers`](@ref) function.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

We can see that these bus IDs are numbered 1 through 5.


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

and update their base voltage to 330 kV:


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

We can also access and update the component name field using the [`get_name`](@ref) and [set_name!](@ref) functions.


[JuliaFormatter] reported by reviewdog 🐶

We can use the [`get_name`](@ref) function to access the `name` field for these components.


[JuliaFormatter] reported by reviewdog 🐶

for i in thermal_gens
@show get_name(i)


[JuliaFormatter] reported by reviewdog 🐶

To update the names we will use the [set_name!](@ref) function.


[JuliaFormatter] reported by reviewdog 🐶

Specifically when using [set_name!](@ref), it is important to note that using


[JuliaFormatter] reported by reviewdog 🐶

calling [`collect`](https://docs.julialang.org/en/v1/base/collections/#Base.collect-Tuple{Any})
on the iterator:
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

set_name!(sys, thermal_gen, get_name(thermal_gen)*"-renamed")


[JuliaFormatter] reported by reviewdog 🐶

Now we can check the names using the [`get_name`](@ref) function again.
```@repl system


[JuliaFormatter] reported by reviewdog 🐶

So far we have seen that we can view different data types in our system using the


[JuliaFormatter] reported by reviewdog 🐶

filter_func::Function,
::Type{T},
sys::System;
subsystem_name = nothing,


[JuliaFormatter] reported by reviewdog 🐶

them using the `set_*` functions.
Follow the next tutorials to learn how to [work with time series](@ref tutorial_time_series).

Comment on lines +69 to +70
1. We make no guarantees on the stability of component structure definitions. We will maintain version stability on the accessor methods.
2. Per-unit conversions are made in the return of data from the accessor functions. (see the [per-unit](https://nrel-sienna.github.io/PowerSystems.jl/stable/explanation/per_unit/#per_unit) section for more details)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
1. We make no guarantees on the stability of component structure definitions. We will maintain version stability on the accessor methods.
2. Per-unit conversions are made in the return of data from the accessor functions. (see the [per-unit](https://nrel-sienna.github.io/PowerSystems.jl/stable/explanation/per_unit/#per_unit) section for more details)
1. We make no guarantees on the stability of component structure definitions. We will maintain version stability on the accessor methods.
2. Per-unit conversions are made in the return of data from the accessor functions. (see the [per-unit](https://nrel-sienna.github.io/PowerSystems.jl/stable/explanation/per_unit/#per_unit) section for more details)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants