Skip to content

Commit

Permalink
Merge branch 'tickets/DM-41209'
Browse files Browse the repository at this point in the history
  • Loading branch information
taranu committed Nov 21, 2023
2 parents 3794218 + 78c8f8d commit e899dfe
Show file tree
Hide file tree
Showing 32 changed files with 798 additions and 2,289 deletions.
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
build/
dist/
multiprofit.egg-info/
*/__pycache__/
__pycache__/
.coverage
.sconsign.dblite
config.log
version.py

# Generated by pip install -e .
python/lsst_multiprofit.egg-info/

# IDE folders and files
.cache/
Expand All @@ -11,6 +18,9 @@ multiprofit.egg-info/
.vscode/
compile_commands.json

# test outputs
tests/.tests

# pytest plugins
.hypothesis/
prof/
Expand Down
4 changes: 4 additions & 0 deletions SConstruct
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- python -*-
from lsst.sconsUtils import scripts
# Python-only package
scripts.BasicSConstruct("multiprofit", disableCc=True, noCfgFile=True)
6 changes: 3 additions & 3 deletions examples/fithsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
import gauss2d.fit as g2f
import matplotlib as mpl
import matplotlib.pyplot as plt
from multiprofit.componentconfig import SersicConfig, SersicIndexConfig
from multiprofit.fit_psf import CatalogExposurePsfABC, CatalogPsfFitterConfig, CatalogPsfFitter
from multiprofit.fit_source import CatalogExposureSourcesABC, CatalogSourceFitterABC, CatalogSourceFitterConfig
from lsst.multiprofit.componentconfig import SersicConfig, SersicIndexConfig
from lsst.multiprofit.fit_psf import CatalogExposurePsfABC, CatalogPsfFitterConfig, CatalogPsfFitter
from lsst.multiprofit.fit_source import CatalogExposureSourcesABC, CatalogSourceFitterABC, CatalogSourceFitterConfig
import numpy as np
from typing import Any, Iterable, Mapping

Expand Down
2 changes: 1 addition & 1 deletion examples/test_gaussians.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
nbenchmark=100, do_like=True, do_residual=True, do_grad=True, do_jac=True,
do_meas_modelfit=False, nsub=4,
)
for x in test:
for x in test:
print(f"re={x['reff']:.3f} q={x['axrat']:.2f}"
f" ang={x['ang']:2.1f} { x['string']}")
print(f'Test complete in {timer() - start:.2f}s')
9 changes: 5 additions & 4 deletions examples/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
from importlib.util import find_spec
import numpy as np
import matplotlib.pyplot as plt
from multiprofit.fitutils import get_model
# TODO: Replace with e.g. fit_source.get_model?
from lsst.multiprofit.fitutils import get_model
import gauss2d as g2
import timeit

Expand Down Expand Up @@ -181,7 +182,7 @@ def get_setup(xdim=15, ydim=15, r_major=1, axrat=1, angle=0, nsub=1,
f'xdim={xdim}',
f'ydim={ydim}',
f'centroid = g2.Centroid({xdim}/2, {ydim}/2)',
f'kernel = g2.Gaussian(centroid=g2.Centroid(0, 0),'
'kernel = g2.Gaussian(centroid=g2.Centroid(0, 0),'
'ellipse=g2.Ellipse(sigma_x=0., sigma_y=0))',
'ellipse = g2.Ellipse(g2.EllipseMajor('
f'r_major={r_major}*g2.M_SIGMA_HWHM, axrat={axrat}, angle={angle}, degrees=True))',
Expand Down Expand Up @@ -318,7 +319,7 @@ def gaussian_test(xdim=49, ydim=51, reffs=None, angs=None, axrats=None, nbenchma
ang_rad = np.deg2rad(ang)
for key in ("dev", "exp"):
times[f"mmf-{key}"] = np.min(timeit.repeat(
f"msf.evaluate().addToImage(img)",
"msf.evaluate().addToImage(img)",
setup=(
f"import numpy as np;"
f"from lsst.shapelet import RadialProfile;"
Expand Down Expand Up @@ -360,7 +361,7 @@ def gradient_test(dimx=5, dimy=4, flux=1e4, reff=2, axrat=0.5, ang=0, bg=1e3,
reff_psf=0, axrat_psf=0.95, ang_psf=0, n_psfs=1, printout=False, plot=False):

if n_psfs > 1:
raise ValueError(f"n_psfs>1 not yet supported")
raise ValueError("n_psfs>1 not yet supported")

cen_x, cen_y = dimx/2., dimy/2.
# Keep this in units of sigma, not re==FWHM/2
Expand Down
Empty file removed multiprofit/__init__.py
Empty file.
1,823 changes: 0 additions & 1,823 deletions multiprofit/multigaussianapproxprofile.py

This file was deleted.

106 changes: 106 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
[build-system]
requires = ["setuptools", "lsst-versions >= 1.3.0"]
build-backend = "setuptools.build_meta"

[project]
name = "lsst-multiprofit"
description = "Astronomical image and source model fitting code."
license = {file = "LICENSE"}
readme = "README.rst"
authors = [
{name="Rubin Observatory Data Management", email="dm-admin@lists.lsst.org"},
]
classifiers = [
"Intended Audience :: Science/Research",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Topic :: Scientific/Engineering :: Astronomy",
]
keywords = [
"astronomy",
"astrophysics",
"fitting",
"lsst",
"models",
"modeling",
]
requires-python = ">=3.10.0"
dependencies = [
"astropy",
"gauss2d",
"gauss2dfit",
"lsst-pex-config",
"lsst-utils",
"importlib_resources",
"matplotlib",
"numpy",
"pydantic",
"scipy",
]
dynamic = ["version"]

[project.urls]
"Homepage" = "https://github.com/lsst-dm/multiprofit"

[project.optional-dependencies]
galsim = ["galsim"]
test = [
"pytest",
]

[tool.setuptools.packages.find]
where = ["python"]

[tool.setuptools.dynamic]
version = { attr = "lsst_versions.get_lsst_version" }

[tool.black]
line-length = 110
target-version = ["py311"]

[tool.isort]
profile = "black"
line_length = 110

[tool.ruff]
exclude = [
"__init__.py",
"examples/fithsc.py",
"examples/test_utils.py",
"tests/*.py",
]
ignore = [
"N802",
"N803",
"N806",
"N812",
"N815",
"N816",
"N999",
"D107",
"D105",
"D102",
"D104",
"D100",
"D200",
"D205",
"D400",
]
line-length = 110
select = [
"E", # pycodestyle
"F", # pycodestyle
"N", # pep8-naming
"W", # pycodestyle
"D", # pydocstyle
]
target-version = "py311"

[tool.ruff.pycodestyle]
max-doc-length = 79

[tool.ruff.pydocstyle]
convention = "numpy"
4 changes: 4 additions & 0 deletions python/lsst/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import pkgutil

__path__ = pkgutil.extend_path(__path__, __name__)

4 changes: 4 additions & 0 deletions python/lsst/multiprofit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import pkgutil

__path__ = pkgutil.extend_path(__path__, __name__)

Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ def _prepare(values, clip=True, out=None):
Prepare the data by optionally clipping and copying, and return the
array that should be subsequently used for in-place calculations.
"""

if clip:
return np.clip(values, 0., 1., out=out)
return np.clip(values, 0.0, 1.0, out=out)
else:
if out is None:
return np.array(values, copy=True)
Expand All @@ -59,7 +58,7 @@ class AsinhStretchSigned(apvis.BaseStretch):
to logarithmic behavior, expressed as a fraction of the
normalized image. Must be in the range between 0 and 1.
Default is 0.1
"""
""" # noqa: W505

def __init__(self, a=0.1):
super().__init__()
Expand All @@ -74,14 +73,14 @@ def __call__(self, values, clip=True, out=None):
np.abs(values, out=values)
np.true_divide(values, self.a, out=values)
np.arcsinh(values, out=values)
np.true_divide(values, np.arcsinh(1. / self.a), out=values)
np.true_divide(1. + signs*values, 2., out=values)
np.true_divide(values, np.arcsinh(1.0 / self.a), out=values)
np.true_divide(1.0 + signs * values, 2.0, out=values)
return values

@property
def inverse(self):
"""A stretch object that performs the inverse operation."""
return SinhStretchSigned(a=1. / np.arcsinh(1. / self.a))
return SinhStretchSigned(a=1.0 / np.arcsinh(1.0 / self.a))


class SinhStretchSigned(apvis.BaseStretch):
Expand All @@ -99,24 +98,24 @@ class SinhStretchSigned(apvis.BaseStretch):
The ``a`` parameter used in the above formula. Default is 1/3.
"""

def __init__(self, a=1. / 3.):
def __init__(self, a=1.0 / 3.0):
super().__init__()
self.a = a

# [docs]
# [docs]

def __call__(self, values, clip=True, out=None):
values = _prepare(values, clip=clip, out=out)
values *= 2.
values -= 1.
values *= 2.0
values -= 1.0
np.true_divide(values, self.a, out=values)
np.sinh(values, out=values)
np.true_divide(values, np.sinh(1. / self.a), out=values)
values += 1.
values /= 2.
np.true_divide(values, np.sinh(1.0 / self.a), out=values)
values += 1.0
values /= 2.0
return values

@property
def inverse(self):
"""A stretch object that performs the inverse operation."""
return AsinhStretchSigned(a=1. / np.sinh(1. / self.a))
return AsinhStretchSigned(a=1.0 / np.sinh(1.0 / self.a))
Loading

0 comments on commit e899dfe

Please sign in to comment.