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

tickets/DM-27208 #18

Merged
merged 32 commits into from
Nov 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b7c2d63
PSFs as Model
pmelchior Aug 9, 2020
99bc177
true PSF photometry for init
pmelchior Aug 11, 2020
9ddf6d7
odd box sizes; SED->spectrum
pmelchior Aug 12, 2020
5828c29
correct PSF width variations
pmelchior Aug 13, 2020
24b607e
correct treatment of single-pixel amplitude inits
pmelchior Aug 13, 2020
78aa56a
added compact source init
pmelchior Aug 13, 2020
0071ff3
bugfixes; reduced point source center step to 0.01 for more stability
pmelchior Aug 14, 2020
fc0fc0c
closes #179
pmelchior Aug 17, 2020
9530f96
removed deconv tutorial; minor updates
pmelchior Aug 27, 2020
5ba11a8
updated tests
pmelchior Aug 27, 2020
fd9fc0c
Merge branch 'master' into psf-model
pmelchior Sep 28, 2020
7517807
ImagePSF returns copy to avoid overwriting parameter; minor bugfixes
pmelchior Sep 28, 2020
0a798c7
allow ImagePSF to shift; clean-up outdated fft code in interpolation
pmelchior Sep 28, 2020
fc5a605
created FunctionPSF; better treatment for constant PSFs
pmelchior Sep 29, 2020
9c61c6c
removed tests for obsolete methods
pmelchior Sep 29, 2020
f33d986
Migrate testing scripts
Oct 5, 2020
ff8874d
Move scarlet_extensions initializations to scarlet
Oct 5, 2020
18fa1bf
Update regression scripts to work
Oct 5, 2020
2aea561
Copy list of blend ids
Oct 5, 2020
5ca9431
Use correct variable name for AWS keys
Oct 5, 2020
51ceff6
Merge pull request #210 from pmelchior/migrate_tests
pmelchior Oct 6, 2020
5b4fc04
Merge branch 'master' into psf-model
pmelchior Oct 6, 2020
24d0bc1
updated regression test to new PSF API
pmelchior Oct 6, 2020
cdf4429
PR comments
pmelchior Oct 8, 2020
3abef76
Merge pull request #204 from pmelchior/psf-model
pmelchior Oct 12, 2020
2c3a2f4
Fix bug in branch names
Oct 12, 2020
0b830f8
Use correct pip requirement for gitpython
Oct 12, 2020
e80e075
Use Travis branch as a command line argument
Oct 13, 2020
974c205
Remove testing error
Oct 13, 2020
0b88ab1
Reactivate all tests
Oct 13, 2020
e39d142
Merge pull request #213 from pmelchior/test-branch-bug
Oct 13, 2020
dd1358b
Merge latest scarlet
Oct 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ install:
# Use pip to install our rtd required packages
- pip install -r docs/rtd-pip-requirements
- python setup.py install

# Run test
script:
- pytest tests
- pytest tests --ignore=tests/test_regressions.py --ignore=tests/test_docs.py --ignore=tests/test_multiresolution.py

# Calculate coverage
#after_success:
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
include _version.txt
include scarlet/testing/lookup.db
13 changes: 6 additions & 7 deletions docs/0-quickstart.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"filters = data[\"filters\"]\n",
"catalog = data[\"catalog\"]\n",
"weights = 1/data[\"variance\"]\n",
"psfs = scarlet.PSF(data[\"psfs\"])"
"psfs = scarlet.ImagePSF(data[\"psfs\"])"
]
},
{
Expand Down Expand Up @@ -113,8 +113,7 @@
"metadata": {},
"outputs": [],
"source": [
"from functools import partial\n",
"model_psf = scarlet.PSF(partial(scarlet.psf.gaussian, sigma=.8), shape=(None, 8, 8))"
"model_psf = scarlet.GaussianPSF(sigma=(0.8,)*len(filters))"
]
},
{
Expand Down Expand Up @@ -200,9 +199,9 @@
"\n",
"You now need to define sources that are going to be fit. The full model, which we will call `Blend`, is a collection of those sources. We provide several pre-built source types, e.g.:\n",
"\n",
"* `RandomSource` fit per-band amplitude and non-parametric morphology starting from uniform random draws for both.\n",
"* `RandomSource` fits per-band amplitude and non-parametric morphology starting from uniform random draws for both.\n",
"* `PointSource` fits centers and per-band amplitude using the observed PSF model.\n",
"* `ExtendedSource` fits per-band amplitude and a non-parametric morphology (which can be constrained to be symmetric and/or monotonic with respect to the center).\n",
"* `ExtendedSource` fits per-band amplitude and a non-parametric morphology (which is constrained to be monotonically decreasing from the center).\n",
"* `ExtendedSource(K=2)` splits an `ExtendedSource` into `K` components that are initially radially separated and stacked on top of each other like a pyramid.\n",
"\n",
"In our example, we assume *prior* knowledge that object 0 is a star, and object 1 should be modeled with two components. Everything else is assumed a single-component galaxy. **We generally recommend `ExtendedSource` as default** if additional information about the source is not available."
Expand All @@ -221,7 +220,7 @@
" elif k == 1:\n",
" new_source = scarlet.ExtendedSource(model_frame, (src['y'], src['x']), observation, K=2)\n",
" else:\n",
" new_source = scarlet.ExtendedSource(model_frame, (src['y'], src['x']), observation)\n",
" new_source = scarlet.ExtendedSource(model_frame, (src['y'], src['x']), observation, compact=True)\n",
" sources.append(new_source)"
]
},
Expand Down Expand Up @@ -334,7 +333,7 @@
"\n",
"### Measure Fluxes\n",
"\n",
"The color information in these plots stems from the per-band amplitude, which could be obtained as `source.spectrum`. However, it is more useful to compute per-band fluxes, which integrate over the morphology. The source spectra plots above have done exactly that. The convention of these fluxes is given by the units and ordering of the original data cube. In the case of multi-component sources, the fluxes of all components are combined."
"The color information in these plots stems from the per-band amplitude, which are computed from the hyperspectral model by integrating over the morphology. The source spectra plots in the right panels above have done exactly that. The convention of these fluxes is given by the units and ordering of the original data cube. In the case of multi-component sources, the fluxes of all components are combined."
]
},
{
Expand Down
1 change: 1 addition & 0 deletions docs/rtd-pip-requirements
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ prompt_toolkit>=2.0.10
sep
gitpython
boto3
gitpython
1 change: 0 additions & 1 deletion docs/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ Tutorials
tutorials/point_source
tutorials/wavelet_model
tutorials/multiresolution

2 changes: 1 addition & 1 deletion docs/tutorials/display.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"catalog = data[\"catalog\"]\n",
"filters = data[\"filters\"]\n",
"weights = 1/data[\"variance\"]\n",
"psfs = scarlet.PSF(data[\"psfs\"])\n",
"psfs = scarlet.ImagePSF(data[\"psfs\"])\n",
"\n",
"observation = scarlet.Observation(\n",
" images, \n",
Expand Down
4 changes: 2 additions & 2 deletions docs/tutorials/multiresolution.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"# Load the HSC PSF data\n",
"psf_hsc = fits.open('../../data/test_resampling/PSF_HSC.fits')[0].data\n",
"Np1, Np2 = psf_hsc[0].shape\n",
"psf_hsc = scarlet.PSF(psf_hsc)\n",
"psf_hsc = scarlet.ImagePSF(psf_hsc)\n",
"\n",
"# Load the HST image data\n",
"hst_hdu = fits.open('../../data/test_resampling/Cut_HST1.fits')\n",
Expand All @@ -66,7 +66,7 @@
"# Load the HST PSF data\n",
"psf_hst = fits.open('../../data/test_resampling/PSF_HST.fits')[0].data\n",
"psf_hst = psf_hst[None,:,:]\n",
"psf_hst = scarlet.PSF(psf_hst)\n",
"psf_hst = scarlet.ImagePSF(psf_hst)\n",
"\n",
"# Scale the HST data\n",
"n1,n2 = np.shape(data_hst)\n",
Expand Down
15 changes: 8 additions & 7 deletions docs/tutorials/point_source.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"import matplotlib\n",
"import matplotlib.pyplot as plt\n",
"# use a better colormap and don't interpolate the pixels\n",
"matplotlib.rc('image', cmap='inferno', interpolation='none')\n",
"matplotlib.rc('image', cmap='inferno', interpolation='none', origin='lower')\n",
"\n",
"import numpy as np\n",
"import scarlet\n",
Expand Down Expand Up @@ -77,12 +77,11 @@
"metadata": {},
"outputs": [],
"source": [
"from functools import partial\n",
"model_psf = scarlet.PSF(partial(scarlet.psf.gaussian, sigma=0.9), shape=(None,31,31))\n",
"model_psf = scarlet.GaussianPSF(sigma=0.9)\n",
"model_frame = scarlet.Frame(images.shape, psfs=model_psf, channels=filters)\n",
"\n",
"observation = scarlet.Observation(images, \n",
" psfs=scarlet.PSF(psfs), \n",
" psfs=scarlet.ImagePSF(psfs), \n",
" weights=weights,\n",
" channels=filters)\n",
"observation = observation.match(model_frame)"
Expand Down Expand Up @@ -169,7 +168,7 @@
"metadata": {},
"outputs": [],
"source": [
"%time it, logL = blend.fit(100, e_rel=1e-4)\n",
"%time it, logL = blend.fit(200, e_rel=1e-4)\n",
"print(f\"scarlet ran for {it} iterations to logL = {logL}\")\n",
"scarlet.display.show_likelihood(blend)\n",
"plt.show()"
Expand Down Expand Up @@ -200,15 +199,17 @@
" norm=norm, \n",
" observation=observation,\n",
" show_rendered=True, \n",
" show_observed=True)\n",
" show_observed=True,\n",
" add_boxes=True\n",
" )\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see that the model overall performs well, especially in fitting the amplitude and locations of the point sources. It is worth noting that the stellar residuals have red rings and blue cores, which suggest that the PSF model of the observation is not quite correct across all bands. The extended sources are less convincing. The effects of the symmetry constraint are clearly visible, and the color between the two galaxies is not very different, so these two sources remain poorly separated."
"We can see that the model overall performs well, especially in fitting the amplitude and locations of the point sources. It is worth noting that the stellar residuals have red rings and blue cores, which suggest that the PSF model of the observation is not quite correct across all bands. The extended sources are less convincing. The colors of the two galaxies are not very different, so these two sources remain poorly separated."
]
}
],
Expand Down
5 changes: 2 additions & 3 deletions docs/tutorials/wavelet_model.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"filters = data[\"filters\"]\n",
"catalog = data[\"catalog\"]\n",
"weights = 1/data[\"variance\"]\n",
"psfs = scarlet.PSF(data[\"psfs\"])"
"psfs = scarlet.ImagePSF(data[\"psfs\"])"
]
},
{
Expand Down Expand Up @@ -161,8 +161,7 @@
"metadata": {},
"outputs": [],
"source": [
"from functools import partial\n",
"model_psf = scarlet.PSF(partial(scarlet.psf.gaussian, sigma=.8), shape=(None, 8, 8))"
"model_psf = scarlet.GaussianPSF(sigma=0.8)"
]
},
{
Expand Down
1 change: 1 addition & 0 deletions scarlet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from . import display
from . import initialization
from . import measure
from . import testing

try:
from ._version import version
Expand Down
16 changes: 10 additions & 6 deletions scarlet/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from .constraint import PositivityConstraint
from .bbox import Box, overlapped_slices
from .fft import fast_zero_pad
from .morphology import Morphology
from .spectrum import Spectrum


class Component(Model):
Expand Down Expand Up @@ -136,13 +138,10 @@ class FactorizedComponent(Component):
"""

def __init__(self, frame, spectrum, morphology):
from .spectrum import Spectrum

assert isinstance(spectrum, Spectrum)
from .morphology import Morphology

assert isinstance(morphology, Morphology)
bbox = spectrum.bbox @ morphology.bbox

bbox = spectrum.bbox @ morphology.bbox[-2:]

super().__init__(frame, children=[spectrum, morphology], bbox=bbox)

Expand All @@ -163,7 +162,12 @@ def get_model(self, *parameters, frame=None):
(Channels, Height, Width) image of the model
"""
spectrum, morphology = self.get_models_of_children(*parameters)
model = spectrum[:, None, None] * morphology[None, :, :]
if len(morphology.shape) == 2:
model = spectrum[:, None, None] * morphology[None, :, :]
elif len(morphology.shape) == 3:
model = spectrum[:, None, None] * morphology
else:
raise AttributeError("morphology must be 2D or 3D")

# project the model into frame (if necessary)
if frame is not None:
Expand Down
4 changes: 3 additions & 1 deletion scarlet/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from astropy.visualization.lupton_rgb import LinearMapping, AsinhMapping
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, Polygon
from matplotlib.ticker import MaxNLocator
from .bbox import Box
from .component import Component

Expand Down Expand Up @@ -181,6 +182,7 @@ def show_likelihood(blend, figsize=None, **kwargs):
fig, ax = plt.subplots(1, 1, figsize=figsize)
ax.plot(blend.log_likelihood, **kwargs)
ax.set_xlabel("Iteration")
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
ax.set_ylabel("log-Likelihood")
return fig

Expand Down Expand Up @@ -230,7 +232,7 @@ def show_observation(
psf_image = np.zeros(observation.images.shape)

if observation.frame.psf is not None:
psf_model = observation.frame.psf.image.copy() # get_model()
psf_model = observation.frame.psf.get_model()
# make PSF as bright as the brightest pixel of the observation
psf_model *= (
observation.images.mean(axis=0).max() / psf_model.mean(axis=0).max()
Expand Down