-
Notifications
You must be signed in to change notification settings - Fork 16
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
Add method to_split in SimpleTilePainter for checking whether to split a tile #89
Conversation
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.
Please add a unit test for _measure_tile_shape
, establishing the results you get for one case (assert on all the return values).
For test_to_split
, it would be good to have a second test case of a tile that isn't split, no?
For the implementation, I think you need to handle the case where diagonals[0] > diagonals[1] and also diagonals[1] < diagonals[0]. One way to do it would be to compute both numbers and then take the min. Another way could be to only define one ratio by directly making sure it's computed so that ratio < 0. Overall I think that ratio computation could also happen in to_split
.
You are duplicating the code that computes the cartesian distance (the formula with np.sqrt
four times). I think this is easily avoided by defining a helper function def compute_distance(i, j)
as a nested function inside _measure_tile_shape
that computes the distance between points i and j, and to call that function a few times, no?
Finally, I think the function that decides whether to split can just take the corners
array, i.e. I would suggest to move the line corners = meta.skycoord_corners.to_pixel(wcs)
to the caller, to be executed before calling is_tile_distorted
(that's the name I would suggest, it's always good to name things that return bools in such a way that it's clear that it's a bool.
@cdeil I just made the updates. |
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 left some more inline comments, mainly suggesting to simplify the implementation of _measure_tile_shape
.
hips/draw/simple.py
Outdated
|
||
return [edges, diagonals, ratio] | ||
|
||
def is_tile_distorted(self, corners: tuple) -> bool: |
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.
Make this a @staticmethod
hips/draw/tests/test_simple.py
Outdated
@@ -101,3 +102,21 @@ def test_draw_debug_image(self): | |||
tile = self.painter.tiles[3] | |||
image = self.painter.image | |||
plot_mpl_single_tile(self.geometry, tile, image) | |||
|
|||
def test_to_split(self): |
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.
Rename to test_ is_tile_distorted
.
hips/draw/simple.py
Outdated
def _measure_tile_shape(corners: tuple) -> List[list]: | ||
"""Compute tile edges and diagonals.""" | ||
|
||
def compute_distance(i: list, j: list) -> float: |
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 find this way you've implemented compute_distance
hard to read.
My suggestion would be that you move the
x, y = corners
to the top and then do this:
def compute_distance(i, j):
return np.sqrt( (x[i] - x[j]) ** 2 + (y[i] - y[j]) ** 2)
i.e. have i and j as the integer index of the corner.
Then you should be able to call it like this:
edge_lengths = [compute_distance(i, (i+1) %4) for i in range(4)]
and like this
diagonal_lengths = [compute_distance(0, 2), compute_distance(1, 3)]
Note that I didn't try this code, I just typed it here.
Can you please try to change the implementation to work this way?
hips/draw/simple.py
Outdated
"""Implement tile splitting criteria as mentioned in :ref:`drawing_algo` page.""" | ||
edges, diagonals, ratio = self._measure_tile_shape(corners) | ||
|
||
return any(i > 300 for i in edges) or \ |
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 think I would find max(edge_lengths) > 300
and equivalently for diagonals easier to read.
bee6ebe
to
1d98898
Compare
@cdeil Okay, I made the changes. However, the test results vary from before. I'm not sure if these are the correct ones or if the previous ones were. |
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 left some more inline comments.
However, the test results vary from before. I'm not sure if these are the correct ones or if the previous ones were.
My guess would be that there was a bug before and that now the results are correct, because the implementation looks good to me.
One thing that would help to make sure it's correct would be if the corner x / y coordinates were visible in the test, i.e. if you'd add an assert_allclose
to make them "visible" and "checkable just by reading the test code". If I see the X / Y coordinates, I can compute by hand what the distances are (basically by duplicating the code you're implementing here though). For me, that would be enough.
If you really want to be sure, and prove to yourself that the implementation is correct now, you could also make a Jupyter notebook where you draw the tile, and then draw circles around the corners with the computed lengths, and see of they go through the corresponding other points, i.e. have the right length. (From my side, this is not necessary, I believe that the implementation you have now is OK, apart from the bug that you have %3
where it should be %4
that I implemented out as an inline comment).
hips/draw/simple.py
Outdated
"""Compute distance between two points.""" | ||
return np.sqrt((x[i] - x[j]) ** 2 + (y[i] - y[j]) ** 2) | ||
|
||
edges = [compute_distance((i + 1) % 3, i) for i in range(4)] |
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.
You now have %3
. Shouldn't this be %4
instead?
hips/draw/simple.py
Outdated
@@ -117,6 +117,30 @@ def _fetch_tiles(self) -> HipsTile: | |||
tile = HipsTile.fetch(tile_meta, url) | |||
yield tile | |||
|
|||
@staticmethod | |||
def _measure_tile_shape(corners: tuple) -> List[list]: | |||
"""Compute tile edges and diagonals.""" |
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.
"Compute tile edges and diagonals" -> "Compute length of tile edges and diagonals"
hips/draw/simple.py
Outdated
return [edges, diagonals, ratio] | ||
|
||
@staticmethod | ||
def _is_tile_distorted(self, corners: tuple) -> bool: |
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.
Remove self
argument here, it's never passed to @staticmethod
s.
You then have to call SimpleTilePainter._measure_tile_shape(corners)
instead of self._measure_tile_shape(corners)
.
Overall my suggestion here would be to move these two functions just out of the SimpleTilePainter
class, and make them standalone functions and put them above or below the SimpleTilePainter
class.
@cdeil Alright, just made the changes. Please check. |
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.
Looks good now. Thanks!
@adl1995 - FYI: I've done a small update to this code in 1b36234 Another thing I noticed was that I had to put
|
As mentioned in issue #84, I have added two methods
to_split
and_measure_tile_shape
which are used for checking whether a tile needs to be split or not. The next step is to perform the actual splitting and modify the projection part to take in the correcttile_width
(half, in case a tile is split).