Skip to content

Commit

Permalink
Merge pull request #263 from ibusko/fit-map-access
Browse files Browse the repository at this point in the history
Adds accessor for the 3D fit parameters in CubeViz
  • Loading branch information
rosteen authored Sep 10, 2020
2 parents 033ff42 + 444d3bf commit 9ad287c
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 24 deletions.
15 changes: 15 additions & 0 deletions jdaviz/configs/cubeviz/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,18 @@
class CubeViz(ConfigHelper, LineListMixin):
"""CubeViz Helper class"""
_default_configuration = 'cubeviz'

@property
def fitted3d(self):
"""
Returns the 3D fitted model parameters.
Returns
-------
parameters : list
list of Quantity 2D arrays, or None.
"""
if hasattr(self.app, '_fitted_3d_model'):
return self.app._fitted_3d_model
else:
return None
15 changes: 8 additions & 7 deletions jdaviz/configs/default/plugins/model_fitting/fitting_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def collect_result(results):
param = getattr(initial_model, name)
param_units.append(param.unit)

# Re-format parameters cube to a list of 2D Quantity arrays.
# Re-format parameters cube to a dict of 2D Quantity arrays.
fitted_parameters = _handle_parameter_units(initial_model,
parameters_cube,
param_units)
Expand Down Expand Up @@ -284,8 +284,8 @@ def _build_model(component_list, expression):
def _handle_parameter_units(model, fitted_parameters_cube, param_units):
"""
Extracts parameter units from a CompoundModel and parameter values
from a list of 2D numpy arrays, and returns a list of 2D Quantity
arrays built the parameter values and units respectively.
from a list of 2D numpy arrays, and returns a dict of 2D Quantity
arrays. The dict values are keyed by the parameter names.
Parameters
----------
Expand All @@ -301,16 +301,17 @@ def _handle_parameter_units(model, fitted_parameters_cube, param_units):
Returns
-------
:list: list with 2D Quantity arrays
:dict: 2D Quantity arrays keyed by parameter name
"""

fitted_parameters_list = []
fitted_parameters_dict = {}

for index in range(len(model.parameters)):
key = model.param_names[index]
_ary = fitted_parameters_cube[index, :, :]
fitted_parameters_list.append(u.Quantity(_ary, param_units[index]))
fitted_parameters_dict[key] = u.Quantity(_ary, param_units[index])

return fitted_parameters_list
return fitted_parameters_dict


def _generate_spaxel_list(spectrum):
Expand Down
4 changes: 4 additions & 0 deletions jdaviz/configs/default/plugins/model_fitting/model_fitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,10 @@ def vue_fit_model_to_cube(self, *args, **kwargs):
self.model_equation,
run_fitter=True)

# Save fitted 3D model in a way that the cubeviz
# helper can access it.
self.app._fitted_3d_model = fitted_model

# Transpose the axis order back
values = np.moveaxis(fitted_spectrum.flux.value, -1, 0)

Expand Down
34 changes: 17 additions & 17 deletions jdaviz/configs/default/plugins/model_fitting/tests/test_fitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,16 @@ def test_cube_fitting_backend():
spectrum, model_list, expression)

# Check that parameter results are formatted as expected.
assert type(fitted_parameters) == list
assert type(fitted_parameters) == dict
assert len(fitted_parameters) == 10

assert type(fitted_parameters[0]) == u.Quantity
assert fitted_parameters[0].unit == u.Jy
assert fitted_parameters[0].shape == (IMAGE_SIZE, IMAGE_SIZE)
assert type(fitted_parameters['amplitude_0']) == u.Quantity
assert fitted_parameters['amplitude_0'].unit == u.Jy
assert fitted_parameters['amplitude_0'].shape == (IMAGE_SIZE, IMAGE_SIZE)

assert type(fitted_parameters[1]) == u.Quantity
assert fitted_parameters[1].unit == u.um
assert fitted_parameters[1].shape == (IMAGE_SIZE, IMAGE_SIZE)
assert type(fitted_parameters['mean_0']) == u.Quantity
assert fitted_parameters['mean_0'].unit == u.um
assert fitted_parameters['mean_0'].shape == (IMAGE_SIZE, IMAGE_SIZE)

# Check that spectrum result is formatted as expected.
assert type(fitted_spectrum) == Spectrum1D
Expand All @@ -115,16 +115,16 @@ def test_cube_fitting_backend():
# interested here in checking the correctness of the data
# packaging into the output products.

assert np.allclose(fitted_parameters[0].value, 1., atol=TOL)
assert np.allclose(fitted_parameters[3].value, 2.5, atol=TOL)
assert np.allclose(fitted_parameters[6].value, -1.7, atol=TOL)
assert np.allclose(fitted_parameters['amplitude_0'].value, 1., atol=TOL)
assert np.allclose(fitted_parameters['amplitude_1'].value, 2.5, atol=TOL)
assert np.allclose(fitted_parameters['amplitude_2'].value, -1.7, atol=TOL)

assert np.allclose(fitted_parameters[1].value, 4.6, atol=TOL)
assert np.allclose(fitted_parameters[4].value, 5.5, atol=TOL)
assert np.allclose(fitted_parameters[7].value, 8.2, atol=TOL)
assert np.allclose(fitted_parameters['mean_0'].value, 4.6, atol=TOL)
assert np.allclose(fitted_parameters['mean_1'].value, 5.5, atol=TOL)
assert np.allclose(fitted_parameters['mean_2'].value, 8.2, atol=TOL)

assert np.allclose(fitted_parameters[2].value, 0.2, atol=TOL)
assert np.allclose(fitted_parameters[5].value, 0.1, atol=TOL)
assert np.allclose(fitted_parameters[8].value, 0.1, atol=TOL)
assert np.allclose(fitted_parameters['stddev_0'].value, 0.2, atol=TOL)
assert np.allclose(fitted_parameters['stddev_1'].value, 0.1, atol=TOL)
assert np.allclose(fitted_parameters['stddev_2'].value, 0.1, atol=TOL)

assert np.allclose(fitted_parameters[9].value, 4.0, atol=TOL)
assert np.allclose(fitted_parameters['amplitude_3'].value, 4.0, atol=TOL)
126 changes: 126 additions & 0 deletions notebooks/concepts/Cube_fit.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cube spectral fitting"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Start the CubeViz application."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Suppress warnings\n",
"import warnings\n",
"\n",
"with warnings.catch_warnings():\n",
" warnings.simplefilter(\"ignore\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"from jdaviz import CubeViz\n",
"\n",
"cubeviz = CubeViz()\n",
"cubeviz.app"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Load cube data."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from astropy.utils.data import download_file\n",
"\n",
"# This file is originally from https://data.sdss.org/sas/dr14/manga/spectro/redux/v2_1_2/7495/stack/manga-7495-12704-LOGCUBE.fits.gz\n",
"# but has been modified to correct some inconsistencies in the way units are parsed\n",
"fn = download_file('https://stsci.box.com/shared/static/28a88k1qfipo4yxc4p4d40v4axtlal8y.fits', cache=True)\n",
"cubeviz.app.load_data(fn)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, go back to the cell where the CubeViz window is.\n",
"\n",
" - click on the plugins tray open button at the top right corner.\n",
" - open the Model Fitting plugin.\n",
" - build the intial model using the resources in the plugin. \n",
" - click on Apply to Cube and wait until it finishes."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once the fit is done, this attribute in the CubeViz object contains the fitted model parameters in the form of a python dictionary.\n",
"\n",
"Each entry in the dictionary corresponds to one parameter in the CompoundModel instance that was generated by the fitter from the arithmetic model expression. The key for each entry is the parameter name as defined by the CompoundModel instance.\n",
"\n",
"Each entry's value is a 2D numpy array with Quantity values representing the corresponding fitted parameter value over all spaxels."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"cubeviz.fitted3d"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

0 comments on commit 9ad287c

Please sign in to comment.