-
Notifications
You must be signed in to change notification settings - Fork 40
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
Extract profiles from PyPSA's Network objects #682
Conversation
88c2646
to
6692946
Compare
Moving the conversation here: I've been discussing with @rouille that it might be cleaner to deal with all inflow profiles in this way -- always normalize the profile based on profile max and assign the Pmax of the added plant to be the profile max (we could transform the normalized profile into MWh via such Pmax later in the workflow). Then assign the pnorm to be the capacity of the added dcline in the subsystem. What do you think @FabianHofmann ? |
a99dbf8
to
df964e4
Compare
Done in last commit:
|
@BainanXia yes, I think this makes sense. Whether to normalize or not does not really make a difference as long as it is consistent. (Just a comment, the profile is rather added to the generator in the subsystem than to the dcline which connects to the system) |
profile = {} | ||
for p, c in profile2carrier.items(): | ||
profile[p] = pd.DataFrame() | ||
for component in ["generators", "storage_units", "stores"]: | ||
if hasattr(network, component): | ||
carrier_in_component = getattr(network, component) | ||
id_carrier = set(carrier_in_component.query("carrier==list(@c)").index) | ||
for t in ["inflow", "p_max_pu"]: | ||
if t in getattr(network, component + "_t"): | ||
ts = getattr(network, component + "_t")[t] | ||
if not ts.empty: | ||
id_ts = set(ts.columns) | ||
idx = list(id_carrier.intersection(id_ts)) | ||
norm = ts[idx].max() if t == "inflow" else 1 | ||
profile[p] = pd.concat([profile[p], ts[idx] / norm], axis=1) | ||
if len(set(c) - set(carrier_in_component.carrier.unique())): | ||
continue | ||
else: | ||
break | ||
profile[p].rename_axis(index="UTC", columns=None, inplace=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure whether this code is a bit bloated.
Pypsa's get_switchable_as_dense
can also be used with 'Store' and 'StorageUnit' and the attribute 'inflow'. Does that make this easier here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I could use get_switchable_as_dense
to access the profiles. I believe I will have then to use a try
/except
logic since depending on the Network
object, hydro/PHS could be located in the SorageUnit
component or Store
component. Is that correct? If we focus on PyPSA-Eur only, the code could be greatly simplified. I was trying to be general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, a hydro/PHS facility could theoretically be a Store component. But it is quite unlikely, since the Store component does not have an "inflow" profile, only the StorageUnit component has. So I'd say for the inflow profile at least, it is not necessary to access stores.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation. I will simplify the logic then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Can you take a look @FabianHofmann? My understanding is that we will never find an hydro, solar and wind profile in the Store
component and hence there is no need to look there.
e8a00c4
to
799a4f4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! This looks good @rouille
eba5dfd
to
2f2a445
Compare
I believe this is good to go. See latest commit where column name of carriers with inflow profiles have been renamed:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Extract profiles from PyPSA's Network objects
Extract profiles from PyPSA's Network objects
Pull Request doc
Purpose
Extract generator and demand profiles from a PyPSA
Network
objectWhat the code is doing
Loop through the
Generator
andStorageUnit
components of aNetwork
object and build user specified profiles through a dictionary mapping profile type (hydro, solar, wind) to carriers (onwind, solar, ror, etc). Inflow profiles are normalized such that the maximum inflow is 1Testing
New unit tests
Where to look
The
get_pypsa_gen_profile
functionUsage Example/Visuals
Note also that PHS does not have inflow profile.
Time estimate
15min