Skip to content

Commit

Permalink
feat: add option to turn off optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
ManonMarchand committed Sep 10, 2024
1 parent 02ad85d commit 29157fb
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 21 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

* Add support of `regions.Regions` [#163]
* Add option to turn off optimization in `fill`. The optimization degrades MOCs that are
way more precise than the given WCS [#166]
* Creation of a MOC from a zone (defined by min/max ra and dec)`MOC.from_zone`
* Creation of a single MOC from a lot of small cones is faster with the new option in
`MOC.from_cones`: the keyword 'union_strategy' can now take the value 'small_cones'.
Expand Down
16 changes: 11 additions & 5 deletions python/mocpy/moc/moc.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,20 +384,26 @@ def contains_lonlat(self, lon, lat, keep_inside=True):

# TODO: implement: def contains_including_surrounding(self, lon, lat, distance)

def fill(self, ax, wcs, **kw_mpl_pathpatch):
def fill(self, ax, wcs, optimize=True, **kw_mpl_pathpatch):
"""
Draw the MOC on a matplotlib axis.
This performs the projection of the cells from the world coordinate system to the pixel image coordinate system.
You are able to specify various styling kwargs for `matplotlib.patches.PathPatch`
(see the `list of valid keywords <https://matplotlib.org/api/_as_gen/matplotlib.patches.PathPatch.html#matplotlib.patches.PathPatch>`__).
This performs the projection of the cells from the world coordinate system to the
pixel image coordinate system. You can provide style keyword arguments as in
`matplotlib.patches.PathPatch`
(see the `list of valid keywords
<https://matplotlib.org/api/_as_gen/matplotlib.patches.PathPatch.html#matplotlib.patches.PathPatch>`__).
Parameters
----------
ax : `matplotlib.axes.Axes`
Matplotlib axis.
wcs : `astropy.wcs.WCS`
WCS defining the World system <-> Image system projection.
optimize : bool, optional
If this is set to True, the MOC will be degraded so that no HEALPix will be
smaller than one pixel as defined by the WCS. It can be useful to deactivate this
optimization for svg outputs or if you take an insert of a WCS. Default is True.
kw_mpl_pathpatch
Plotting arguments for `matplotlib.patches.PathPatch`.
Expand All @@ -418,7 +424,7 @@ def fill(self, ax, wcs, **kw_mpl_pathpatch):
>>> ax = fig.add_subplot(projection=wcs)
>>> moc.fill(ax, wcs, color='blue')
"""
fill.fill(self, ax, wcs, **kw_mpl_pathpatch)
fill.fill(self, ax, wcs, optimize=optimize, **kw_mpl_pathpatch)

def border(self, ax, wcs, **kw_mpl_pathpatch):
"""
Expand Down
8 changes: 6 additions & 2 deletions python/mocpy/moc/plot/fill.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def add_patches_to_mpl_axe(patches, ax, wcs, **kw_mpl_pathpatch):
_set_wcs(ax, wcs)


def fill(moc, ax, wcs, **kw_mpl_pathpatch):
def fill(moc, ax, wcs, *, optimize=True, **kw_mpl_pathpatch):
"""Fill the figure's ax with the patches.
Parameters
Expand All @@ -122,11 +122,15 @@ def fill(moc, ax, wcs, **kw_mpl_pathpatch):
ax : matplotlib.pyplot.axes
wcs : astropy.wcs.WCS
projection from astropy
optimize : bool, optional
If this is set to True, the MOC will be degraded so that no HEALPix will be
smaller than one pixel as defined by the WCS. It can be useful to deactivate this
optimization for svg outputs or if you take an insert of a WCS. Default to True.
"""
# Simplify the MOC for plotting purposes:
# 1. Degrade the MOC if the FOV is enough big so that we cannot see the smallest HEALPix cells.
# 2. For small FOVs, plot the MOC & POLYGONAL_MOC_FROM_FOV.
moc_to_plot = build_plotting_moc(moc=moc, wcs=wcs)
moc_to_plot = build_plotting_moc(moc=moc, wcs=wcs, optimize=optimize)

# If the FOV contains no cells, then moc_to_plot (i.e. the intersection between the moc
# and the MOC created from the FOV polygon) will be empty.
Expand Down
29 changes: 15 additions & 14 deletions python/mocpy/moc/plot/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,21 @@ def _set_wcs(ax, wcs):
ax.set_ylim([y_min, y_max])


def build_plotting_moc(moc, wcs):
def build_plotting_moc(moc, wcs, optimize=True):
"""Plot a moc."""
# Get the WCS cdelt giving the deg.px^(-1) resolution.
cdelt = wcs.wcs.cdelt
# Convert in rad.px^(-1)
cdelt = np.abs((2 * np.pi / 360) * cdelt[0])
# Get the minimum depth such as the resolution of a cell is contained in 1px.
depth_res = int(np.floor(np.log2(np.sqrt(np.pi / 3) / cdelt)))
depth_res = max(depth_res, 0)
# Degrade the moc to that depth for plotting purposes. It is not necessary to plot pixels
# that we will not see because they are contained in 1px.
moc_plot = moc
if moc.max_order > depth_res:
moc_plot = moc.degrade_to_order(depth_res)
moc_plot = moc # creates a copy to keep the original moc untouched
if optimize:
# Get the WCS cdelt giving the deg.px^(-1) resolution.
cdelt = wcs.wcs.cdelt
# Convert in rad.px^(-1)
cdelt = np.abs((2 * np.pi / 360) * cdelt[0])
# Get the minimum depth such as the resolution of a cell is contained in 1px.
depth_res = int(np.floor(np.log2(np.sqrt(np.pi / 3) / cdelt)))
depth_res = max(depth_res, 0)
# Degrade the moc to that depth for plotting purposes. It is not necessary to plot pixels
# that we will not see because they are contained in 1px.
if moc.max_order > depth_res:
moc_plot = moc.degrade_to_order(depth_res)

# Get the MOC delimiting the FOV polygon
width_px = int(wcs.wcs.crpix[0] * 2.0) # Supposing the wcs is centered in the axis
Expand All @@ -56,7 +57,7 @@ def build_plotting_moc(moc, wcs):
Y_px = np.append(Y_px, Y[-1, :-1])
Y_px = np.append(Y_px, Y[1:, 0][::-1])

# Disable the output of warnings when encoutering NaNs.
# Disable the output of warnings when encountering NaNs.
warnings.filterwarnings("ignore")
# Inverse projection from pixel coordinate space to the world coordinate space
viewport = pixel_to_skycoord(X_px, Y_px, wcs)
Expand Down

0 comments on commit 29157fb

Please sign in to comment.