+
+
Date: Wed, 29 Jun 2022 15:52:00 -0400
Subject: [PATCH 6/9] Display fit results in its own section and fix plot
titles
---
CHANGES.rst | 3 ++-
.../aper_phot_simple/aper_phot_simple.py | 13 ++++++++-----
.../aper_phot_simple/aper_phot_simple.vue | 19 ++++++++++++++++++-
3 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index 8497e320da..f677898a12 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -28,7 +28,8 @@ Imviz
^^^^^
- Added the ability to fit Gaussian1D model to radial profile in
- Simple Aperture Photometry plugin. [#1409]
+ Simple Aperture Photometry plugin. Radial profile now centers
+ on source centroid, not Subset center. [#1409]
Mosviz
^^^^^^
diff --git a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py
index bec06736d3..fde67ca12a 100644
--- a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py
+++ b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py
@@ -47,6 +47,7 @@ class SimpleAperturePhotometry(TemplateMixin, DatasetSelectMixin):
plot_available = Bool(False).tag(sync=True)
radial_plot = Any('').tag(sync=True, **widget_serialization)
fit_radial_profile = Bool(False).tag(sync=True)
+ fit_results = List().tag(sync=True)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -349,7 +350,7 @@ def vue_do_aper_phot(self, *args, **kwargs):
label=comp.units or 'Value')]
if self.current_plot_type == "Radial Profile":
- self._fig.title = 'Radial profile from Subset center'
+ self._fig.title = 'Radial profile from source centroid'
x_data, y_data = _radial_profile(
phot_aperstats.data_cutout, phot_aperstats.bbox, phot_aperstats.centroid,
raw=False)
@@ -357,7 +358,7 @@ def vue_do_aper_phot(self, *args, **kwargs):
scales={'x': line_x_sc, 'y': line_y_sc},
marker_size=32, colors='gray')
else: # Radial Profile (Raw)
- self._fig.title = 'Raw radial profile from Subset center'
+ self._fig.title = 'Raw radial profile from source centroid'
x_data, y_data = _radial_profile(
phot_aperstats.data_cutout, phot_aperstats.bbox, phot_aperstats.centroid,
raw=True)
@@ -419,16 +420,18 @@ def vue_do_aper_phot(self, *args, **kwargs):
f'{x:.4e} ({phot_table["aperture_sum_counts_err"][0]:.4e})'})
else:
tmp.append({'function': key, 'result': str(x)})
+
# Also display fit results
+ fit_tmp = []
if fit_model is not None and isinstance(fit_model, Gaussian1D):
- model_name = fit_model.__class__.__name__
for param in ('fwhm', 'mean', 'amplitude'):
p_val = getattr(fit_model, param)
if isinstance(p_val, Parameter):
p_val = p_val.value
- tmp.append({'function': f'{model_name}_{param}',
- 'result': f'{p_val:.4e}'})
+ fit_tmp.append({'function': param, 'result': f'{p_val:.4e}'})
+
self.results = tmp
+ self.fit_results = fit_tmp
self.result_available = True
self.radial_plot = self._fig
self.bqplot_figs_resize = [self._fig]
diff --git a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.vue b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.vue
index b606385bc0..a4d285f24b 100644
--- a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.vue
+++ b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.vue
@@ -133,8 +133,25 @@
+
+ Gaussian Fit Results
+
+ Result
+ Value
+
+
+
+ {{ item.function }}
+
+ {{ item.result }}
+
+
+
- Results
+ Photometry Results
Result
Value
From a48f801da009e5124f99534d6d3ba29de3f0ab9c Mon Sep 17 00:00:00 2001
From: "Pey Lian Lim (Github)" <2090236+pllim@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:55:33 -0400
Subject: [PATCH 7/9] Update phot plugin doc
---
docs/imviz/plugins.rst | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/docs/imviz/plugins.rst b/docs/imviz/plugins.rst
index 7582d8bd00..0571d4a92d 100644
--- a/docs/imviz/plugins.rst
+++ b/docs/imviz/plugins.rst
@@ -184,6 +184,13 @@ results are displayed under the :guilabel:`CALCULATE` button.
Radial profile (raw).
+If you opted to fit a `~astropy.modeling.functional_models.Gaussian1D`
+to the radial profile, the last fitted model parameters will be displayed
+under the radial profile plot. The model itself can be obtained by as follows.
+See :ref:`astropy:astropy-modeling` on how to manipulate the model::
+
+ my_gaussian1d = imviz.app.fitted_models['phot_radial_profile']
+
You can also retrieve the photometry results as `~astropy.table.QTable` as follows,
assuming ``imviz`` is the instance of your Imviz application::
@@ -260,12 +267,6 @@ The columns are as follow:
Once you have the results in a table, you can further manipulated them as
documented in :ref:`astropy:astropy-table`.
-If you opted to fit a `~astropy.modeling.functional_models.Gaussian1D`
-to the radial profile, the last fitted model can be obtained by as follows.
-See :ref:`astropy:astropy-modeling` on how to manipulate the model::
-
- my_gaussian1d = imviz.app.fitted_models['phot_radial_profile']
-
.. _imviz-export-plot:
Export Plot
From 2da055acc4c41d4d56097aa0702924f7d3d2cbad Mon Sep 17 00:00:00 2001
From: "Pey Lian Lim (Github)" <2090236+pllim@users.noreply.github.com>
Date: Thu, 30 Jun 2022 18:54:21 -0400
Subject: [PATCH 8/9] Gaussian1D: Fix mean and bind amplitude like imexam PR
241
---
.../imviz/plugins/aper_phot_simple/aper_phot_simple.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py
index fde67ca12a..a772ac22c2 100644
--- a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py
+++ b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py
@@ -367,15 +367,17 @@ def vue_do_aper_phot(self, *args, **kwargs):
default_size=1, colors='gray')
# Fit Gaussian1D to radial profile data.
+ # mean is fixed at 0 because we recentered to centroid.
if self.fit_radial_profile:
fitter = LevMarLSQFitter()
y_max = y_data.max()
- x_mean = x_data[np.where(y_data == y_max)].mean()
std = 0.5 * (phot_table['semimajor_sigma'][0] +
phot_table['semiminor_sigma'][0])
if isinstance(std, u.Quantity):
std = std.value
- gs = Gaussian1D(amplitude=y_max, mean=x_mean, stddev=std)
+ gs = Gaussian1D(amplitude=y_max, mean=0, stddev=std,
+ fixed={'mean': True, 'amplitude': True},
+ bounds={'amplitude': (y_max * 0.5, y_max)})
with warnings.catch_warnings(record=True) as warns:
fit_model = fitter(gs, x_data, y_data)
if len(warns) > 0:
@@ -424,7 +426,7 @@ def vue_do_aper_phot(self, *args, **kwargs):
# Also display fit results
fit_tmp = []
if fit_model is not None and isinstance(fit_model, Gaussian1D):
- for param in ('fwhm', 'mean', 'amplitude'):
+ for param in ('fwhm', 'amplitude'): # mean is fixed at 0
p_val = getattr(fit_model, param)
if isinstance(p_val, Parameter):
p_val = p_val.value
From 03f0e5f958b88de5e02057940a68a2a2e86d71ca Mon Sep 17 00:00:00 2001
From: "Pey Lian Lim (Github)" <2090236+pllim@users.noreply.github.com>
Date: Fri, 1 Jul 2022 12:42:28 -0400
Subject: [PATCH 9/9] Imviz phot curve of growth also from centroid
---
CHANGES.rst | 2 +-
.../aper_phot_simple/aper_phot_simple.py | 22 ++++++++++++-------
.../imviz/tests/test_simple_aper_phot.py | 9 ++++----
3 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index f677898a12..ed8cff47fe 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -28,7 +28,7 @@ Imviz
^^^^^
- Added the ability to fit Gaussian1D model to radial profile in
- Simple Aperture Photometry plugin. Radial profile now centers
+ Simple Aperture Photometry plugin. Radial profile and curve of growth now center
on source centroid, not Subset center. [#1409]
Mosviz
diff --git a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py
index a772ac22c2..a49eba7569 100644
--- a/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py
+++ b/jdaviz/configs/imviz/plugins/aper_phot_simple/aper_phot_simple.py
@@ -332,10 +332,10 @@ def vue_do_aper_phot(self, *args, **kwargs):
line_y_sc = bqplot.LinearScale()
if self.current_plot_type == "Curve of Growth":
- self._fig.title = 'Curve of growth from Subset center'
+ self._fig.title = 'Curve of growth from source centroid'
x_arr, sum_arr, x_label, y_label = _curve_of_growth(
- comp_data, aperture, phot_table['sum'][0], wcs=data.coords,
- background=bg, pixarea_fac=pixarea_fac)
+ comp_data, phot_aperstats.centroid, aperture, phot_table['sum'][0],
+ wcs=data.coords, background=bg, pixarea_fac=pixarea_fac)
self._fig.axes = [bqplot.Axis(scale=line_x_sc, label=x_label),
bqplot.Axis(scale=line_y_sc, orientation='vertical',
label=y_label)]
@@ -482,7 +482,7 @@ def _radial_profile(radial_cutout, reg_bb, centroid, raw=False):
return x_arr, y_arr
-def _curve_of_growth(data, aperture, final_sum, wcs=None, background=0, n_datapoints=10,
+def _curve_of_growth(data, centroid, aperture, final_sum, wcs=None, background=0, n_datapoints=10,
pixarea_fac=None):
"""Calculate curve of growth for aperture photometry.
@@ -491,8 +491,14 @@ def _curve_of_growth(data, aperture, final_sum, wcs=None, background=0, n_datapo
data : ndarray or `~astropy.units.Quantity`
Data for the calculation.
+ centroid : tuple of int
+ ``ApertureStats`` centroid or desired center in ``(x, y)``.
+
aperture : obj
- ``photutils`` aperture object.
+ ``photutils`` aperture to use, except its center will be
+ changed to the given ``centroid``. This is because the aperture
+ might be hand-drawn and a more accurate centroid has been
+ recalculated separately.
final_sum : float or `~astropy.units.Quantity`
Aperture sum that is already calculated in the
@@ -532,20 +538,20 @@ def _curve_of_growth(data, aperture, final_sum, wcs=None, background=0, n_datapo
if isinstance(aperture, CircularAperture):
x_label = 'Radius (pix)'
x_arr = np.linspace(0, aperture.r, num=n_datapoints)[1:]
- aper_list = [CircularAperture(aperture.positions, cur_r) for cur_r in x_arr[:-1]]
+ aper_list = [CircularAperture(centroid, cur_r) for cur_r in x_arr[:-1]]
elif isinstance(aperture, EllipticalAperture):
x_label = 'Semimajor axis (pix)'
x_arr = np.linspace(0, aperture.a, num=n_datapoints)[1:]
a_arr = x_arr[:-1]
b_arr = aperture.b * a_arr / aperture.a
- aper_list = [EllipticalAperture(aperture.positions, cur_a, cur_b, theta=aperture.theta)
+ aper_list = [EllipticalAperture(centroid, cur_a, cur_b, theta=aperture.theta)
for (cur_a, cur_b) in zip(a_arr, b_arr)]
elif isinstance(aperture, RectangularAperture):
x_label = 'Width (pix)'
x_arr = np.linspace(0, aperture.w, num=n_datapoints)[1:]
w_arr = x_arr[:-1]
h_arr = aperture.h * w_arr / aperture.w
- aper_list = [RectangularAperture(aperture.positions, cur_w, cur_h, theta=aperture.theta)
+ aper_list = [RectangularAperture(centroid, cur_w, cur_h, theta=aperture.theta)
for (cur_w, cur_h) in zip(w_arr, h_arr)]
else:
raise TypeError(f'Unsupported aperture: {aperture}')
diff --git a/jdaviz/configs/imviz/tests/test_simple_aper_phot.py b/jdaviz/configs/imviz/tests/test_simple_aper_phot.py
index 159d6e9d49..ac602550b4 100644
--- a/jdaviz/configs/imviz/tests/test_simple_aper_phot.py
+++ b/jdaviz/configs/imviz/tests/test_simple_aper_phot.py
@@ -168,7 +168,7 @@ def test_plugin_wcs_dithered(self):
# Curve of growth
phot_plugin.current_plot_type = 'Curve of Growth'
phot_plugin.vue_do_aper_phot()
- assert phot_plugin._fig.title == 'Curve of growth from Subset center'
+ assert phot_plugin._fig.title == 'Curve of growth from source centroid'
class TestSimpleAperPhot_NoWCS(BaseImviz_WCS_NoWCS):
@@ -298,11 +298,12 @@ def test_curve_of_growth(with_unit):
RectangularAperture(cen, 20, 15))
for aperture in apertures:
- final_sum = ApertureStats(data, aperture).sum
+ astat = ApertureStats(data, aperture)
+ final_sum = astat.sum
if pixarea_fac is not None:
final_sum = final_sum * pixarea_fac
x_arr, sum_arr, x_label, y_label = _curve_of_growth(
- data, aperture, final_sum, background=bg, pixarea_fac=pixarea_fac)
+ data, astat.centroid, aperture, final_sum, background=bg, pixarea_fac=pixarea_fac)
assert_allclose(x_arr, [2, 4, 6, 8, 10, 12, 14, 16, 18, 20])
assert y_label == expected_ylabel
@@ -321,5 +322,5 @@ def test_curve_of_growth(with_unit):
assert_allclose(sum_arr, [3, 12, 27, 48, 75, 108, 147, 192, 243, 300])
with pytest.raises(TypeError, match='Unsupported aperture'):
- _curve_of_growth(data, EllipticalAnnulus(cen, 3, 8, 5), 100,
+ _curve_of_growth(data, cen, EllipticalAnnulus(cen, 3, 8, 5), 100,
pixarea_fac=pixarea_fac)