-
Notifications
You must be signed in to change notification settings - Fork 28
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
feat: add function to assign demand to buses proportional to population #235
Conversation
1ea6767
to
748fe4d
Compare
filtered_branch = branch.query("SUB_1_ID != SUB_2_ID") | ||
from_cap = filtered_branch.groupby("SUB_1_ID").sum()["rateA"] | ||
to_cap = filtered_branch.groupby("SUB_2_ID").sum()["rateA"] | ||
sub_cap = from_cap.combine(to_cap, lambda x, y: x + y, fill_value=0) |
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 was thinking about refactoring calculate_substation_capacity
function in powersimdata/design/transmission/substations.py
, which currently takes a grid object as input, but failed to come up with a compatible idea given the column names are different as well...Let's keep these lines here then.
subs_per_zip = filtered_subs.value_counts("ZIP") | ||
zip_load_substations = subs_per_zip * const.substation_load_share | ||
zip_load_substations = zip_load_substations.round().clip(lower=1) | ||
zip_assigned_population = (zip_data["population"] / zip_load_substations).dropna() |
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.
When I was reading through the reference code from collaborators, I was thinking whether we should distribute load (population) proportional to the substation capacities instead of uniformly. Do you think that will make a difference?
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.
It will definitely make some kind of difference, but I'm not not sure in which general direction the difference will be. Thinking about a low-medium density area, I would imagine that the population is fairly evenly spread out, and so distributing uniformly probably makes sense, since a high-capacity substation may just be a collector, not in response to a pocket of density. However, in an area that truly has different densities, higher-capacity substations may actually be in reaction to higher density. Without further information, I'm not sure what the best conclusion is.
If we run a simulation with this approach and find issues, then I think we may need to revisit this question. I think it's also potentially related to #234; we may want to patch the algorithm, or we may alternatively want to patch the data that feeds the algorithm.
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.
Very nice. Thanks!
ed5b489
to
53d6c00
Compare
I chatted with @rouille today, and he raised a suggestion: should these CSVs live in the blob storage, rather than the repo? |
Good call. Looking at the size of the two files, <10M in total. I would say it won't hurt to leave it in the repo for now so that it is easier to move around. But it is also clean put them in the blob storage if we have a folder structure in mind (we still have decent amount of files in the repo now). Again, your choice. |
b4eba4e
to
1e06ffa
Compare
This feature has been refactored to get the county and ZIP data files from blob storage, rather than from the repo itself. The new call signature (including changes to from prereise.gather.griddata.hifld.data_process.demand import assign_demand_to_buses
from prereise.gather.griddata.hifld.data_process.generators import build_plant
from prereise.gather.griddata.hifld.data_process.transmission import build_transmission
branch, bus, sub, dcline = build_transmission()
generators = build_plant(bus, sub)
assign_demand_to_buses(sub, branch, generators, bus) |
c1448bf
to
27d0e67
Compare
feat: add function to assign demand to buses proportional to population
feat: add function to assign demand to buses proportional to population
feat: add function to assign demand to buses proportional to population
feat: add function to assign demand to buses proportional to population
feat: add function to assign demand to buses proportional to population
feat: add function to assign demand to buses proportional to population
feat: add function to assign demand to buses proportional to population
feat: add function to assign demand to buses proportional to population
Pull Request doc
Purpose
Estimates population per substation, using data from simplemaps.com, and uses this information to add demand to buses. This is a re-implementation of the approach taken by the collaborators. Closes #229.
What the code is doing
We add a new module
prereise.gather.griddata.hifld.data_process.demand
with a single functionassign_demand_to_buses
. This function:substation_load_share
fraction within const.py) but no less than one, unless there are no substations within that ZIP. These are considered as 'load substations'.Besides demand.py, all other changes are data/documentation.
Testing
Tested manually.
Usage Example/Visuals
A
"Pd"
column is added inplace to thebus
dataframe:We need the generators to be able to preferentially assign demand to non-generator buses, and we need branch capacities to preferentially assign demand to higher-capacity substations when multiple substations are available within an area (ZIP or county). Generating the transformers and estimating branch impedances and capacities should probably be added to
build_transmission
as part of fulfillment of #226.I demonstrate using the "line2sub" method since I have more faith in line coordinates than line substation names, based on some exploration with DC lines: #233 (comment). I suggest that we also switch to this as default as part of #226.
Time estimate
1 hour. The code itself isn't too long, but it's some fairly dense pandas.