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

Distance to Ports #90

Merged
merged 16 commits into from
Mar 4, 2021
Merged

Distance to Ports #90

merged 16 commits into from
Mar 4, 2021

Conversation

MRossol
Copy link
Collaborator

@MRossol MRossol commented Feb 17, 2021

No description provided.

@MRossol MRossol added the feature New feature or request label Feb 17, 2021
@MRossol MRossol force-pushed the offshore_db branch 2 times, most recently from 1d992ca to df8fa0b Compare February 18, 2021 17:52
@codecov-io
Copy link

codecov-io commented Feb 18, 2021

Codecov Report

Merging #90 (0450c34) into master (01dfce1) will increase coverage by 0.41%.
The diff coverage is 86.07%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #90      +/-   ##
==========================================
+ Coverage   78.93%   79.34%   +0.41%     
==========================================
  Files          68       73       +5     
  Lines        7239     7553     +314     
==========================================
+ Hits         5714     5993     +279     
- Misses       1525     1560      +35     
Flag Coverage Δ
unittests 79.34% <86.07%> (+0.41%) ⬆️

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

Impacted Files Coverage Δ
reVX/utilities/exclusions_converter.py 75.86% <ø> (+2.46%) ⬆️
reVX/wind_dirs/mean_wind_dirs_cli.py 69.90% <ø> (ø)
tests/test_setbacks.py 96.51% <ø> (-0.05%) ⬇️
reVX/wind_setbacks/wind_setbacks_cli.py 49.00% <45.45%> (ø)
reVX/offshore/dist_to_ports_cli.py 65.55% <65.55%> (ø)
tests/test_plexos_plants.py 84.61% <66.66%> (-2.89%) ⬇️
reVX/wind_setbacks/wind_setbacks.py 75.07% <75.00%> (ø)
tests/test_dist_to_ports.py 94.82% <94.82%> (ø)
reVX/offshore/dist_to_ports.py 95.55% <95.55%> (ø)
reVX/config/dist_to_ports.py 100.00% <100.00%> (ø)
... and 14 more

@MRossol
Copy link
Collaborator Author

MRossol commented Mar 2, 2021

@grantbuster, this feature is "complete" and ready for review if you have time. A high level review is fine, but I would love your thoughts, inputs on the two similar run kwargs:

  • cost_layer: this is the existing layer in the excl_h5 file that is used to create the cost layer, it needs to be the distance from each offshore pixel to land. In hindsight, I don't love the name, its ambiguous, dist_layer might be better BUT:
  • dist_layer: this is the layer to either save the distance_to_ports layer to, or to update (if update = True), maybe this should be ports_layer instead?

rename layer kwargs
rename update kwarg to update_layer due to config method conflict
Parameters
----------
config : dict
Dictionary with pre-extracted config input group.
Copy link
Member

Choose a reason for hiding this comment

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

Can't this also be a filepath to config?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

good question, do you know? ;-) I can look

Copy link
Member

Choose a reason for hiding this comment

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

haha yes, str filepath to json config or pre-extracted config in dict form

Parameters
----------
ports : str
Path to shape file containing ports to compute least cost distance
Copy link
Member

Choose a reason for hiding this comment

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

Why are ports a shape file? Shouldn't they just be lat/lon point locations?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's what I got from the GDS team, technically your correct. I'll make the parser more dynamic

Copy link
Member

Choose a reason for hiding this comment

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

Yeah Im not surprised that they would have shape files inputs but it seems like all we need is point locations so like a meta data file might be worth handling.

pixel_coords = offshore_lat_lon[['latitude', 'longitude']].values
tree = cKDTree(pixel_coords) # pylint: disable=not-callable

port_coords = ports[['LATITUDE', 'LONGITUDE']].values
Copy link
Member

Choose a reason for hiding this comment

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

this seems like a bad hard-coded set of coordinate labels. Can that lat/lon label parser you wrote handle this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch! Yes it should, that is a super handy new util!

shore pixels set to 9999.
profile : dict
Profile (transform, crs, etc.) of arr raster
lat_lon : pandas.DataFrame
Copy link
Member

Choose a reason for hiding this comment

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

This docstring confuses me. How does the dataframe map the offshore pixel coordinates to the array indices? How would i use this object? What is the index of the dataframe? What are the columns? Are the offshore "pixels" the exclusion pixels or the wind resource pixels? This comment applies to a few places where this variables is passed around.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this is all based on the exclusion arrays. This dataframe is a flattened list of the lat, lon, row, col coordinates for all offshore pixels. I'll make the docstrings clearer, you've really raised our docstring bar, I think its great but man are our old modules going to look bad ;-)

Copy link
Member

Choose a reason for hiding this comment

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

Haha yes most of the bar raising is because i cant figure out how to use our old code....


class DistanceToPorts:
"""
Compute the distance to port in km
Copy link
Member

Choose a reason for hiding this comment

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

Maybe consider adding more description of the use case in the class docstring. For example, "use this class to compute the least cost distance from the exclusion grid pixels to port locations. The distance to shore layer will be used to calculate least cost paths around land masses and other such obstructions" or something like that?

And also maybe write down somewhere that you can update the least cost exclusion layer by adding in new ports? So like if you get one new port you can just run with a single input port and an existing least cost distnace layer? I think that is really powerful but kind of implicit right now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can do

ports['row'] = pixels['row'].values
ports['col'] = pixels['col'].values
ports['dist_to_pixel'] = cls._haversine_distance(port_coords,
pixel_coords[idx])
Copy link
Member

Choose a reason for hiding this comment

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

Is this mapping the ports to their respective nearest single 90m pixels? If so, should specify in docstring. Current statement of "port locations and their mapping to the offshore pixels" makes it sound like it could be port -> 1 or more offshore pixels.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

not quite, it is to the nearest offshore 90m pixel. The issue is that sometimes the ports sit inland based on our dist_to_coast raster

saved, if None use the ports file-name, by default None
chunks : tuple, optional
Chunk size of dataset in .h5 file, by default (128, 128)
max_workers : int, optional
Copy link
Member

Choose a reason for hiding this comment

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

The parallelization scheme for this is by port right? So if adding one new port to the layer, max_workers should be 1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes, but if your run with update_layer it could have multiple new ports in the shape file (or future .csv)

@@ -354,7 +354,7 @@ def _haversine_dist(cls, plant_coords, sc_coords):
if plant_coords.shape[0] == 1:
dist = dist.flatten()

R = 6373.0 # radius of the earth in kilometers
R = 6371.0 # radius of the earth in kilometers
Copy link
Member

Choose a reason for hiding this comment

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

Did the earth shrink?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I for the life of me could not figure out where you got 6373! Everything i found online said 6371, we should get consensus on that...

Copy link
Member

Choose a reason for hiding this comment

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

Fortunately i think this is just a scalar on the distance so the relative and nearest distances should be all good. The radius depends on where you're measuring since the earth is not a perfect sphere. seems to be 6378 at the equator. But yes i'm also seeing 6371 as the average. Might have been a typo....



@pytest.mark.parametrize('ports_layer', [None, 'test'])
def test_cli(runner, ports_layer):
Copy link
Member

Choose a reason for hiding this comment

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

I thought you were going to keep the heatmap plot output as an option in the test for this feature? This is definitely a feature thats easier to visualize.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

brain fart, I'll add in that function.

@grantbuster
Copy link
Member

@MRossol what about input_dist_layer and output_dist_layer?

@MRossol
Copy link
Collaborator Author

MRossol commented Mar 3, 2021

input and output dist_layer works for me!

@MRossol
Copy link
Collaborator Author

MRossol commented Mar 3, 2021

@grantbuster I think I got all of the changes

@MRossol MRossol merged commit 959d695 into master Mar 4, 2021
@MRossol MRossol deleted the offshore_db branch March 4, 2021 16:14
github-actions bot pushed a commit that referenced this pull request Mar 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants