diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 3989c638..9ff01961 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -37,7 +37,6 @@ build: python: install: - - requirements: requirements.txt # Path to your requirements.txt file - requirements: docs/requirements.txt # Path to your requirements.txt file - method: pip - path: . # Install the package itself + path: .[dev] # Install the package itself diff --git a/astrophot/__init__.py b/astrophot/__init__.py index f863ad11..7fc1e3e2 100644 --- a/astrophot/__init__.py +++ b/astrophot/__init__.py @@ -1,6 +1,3 @@ -import argparse -import requests -import torch from . import config, models, plots, utils, fit, image, errors from .param import forward, Param, Module @@ -38,110 +35,6 @@ __author__ = "Connor Stone" __email__ = "connorstone628@gmail.com" - -def run_from_terminal() -> None: - """ - Running from terminal no longer supported. This is only used for convenience to download the tutorials. - - """ - config.logger.debug("running from the terminal, not sure if it will catch me.") - parser = argparse.ArgumentParser( - prog="astrophot", - description="Fast and flexible astronomical image photometry package. For the documentation go to: https://astrophot.readthedocs.io", - epilog="Please see the documentation or contact connor stone (connorstone628@gmail.com) for further assistance.", - ) - parser.add_argument( - "filename", - nargs="?", - metavar="configfile", - help="the path to the configuration file. Or just 'tutorial' to download tutorials.", - ) - # parser.add_argument( - # "--config", - # type=str, - # default="astrophot", - # choices=["astrophot", "galfit"], - # metavar="format", - # help="The type of configuration file being being provided. One of: astrophot, galfit.", - # ) - parser.add_argument( - "-v", - "--version", - action="version", - version=f"%(prog)s {__version__}", - help="print the current AstroPhot version to screen", - ) - # parser.add_argument( - # "--log", - # type=str, - # metavar="logfile.log", - # help="set the log file name for AstroPhot. use 'none' to suppress the log file.", - # ) - # parser.add_argument( - # "-q", - # action="store_true", - # help="quiet flag to stop command line output, only print to log file", - # ) - # parser.add_argument( - # "--dtype", - # type=str, - # choices=["float64", "float32"], - # metavar="datatype", - # help="set the float point precision. Must be one of: float64, float32", - # ) - # parser.add_argument( - # "--device", - # type=str, - # choices=["cpu", "gpu"], - # metavar="device", - # help="set the device for AstroPhot to use for computations. Must be one of: cpu, gpu", - # ) - - args = parser.parse_args() - - if args.log is not None: - config.set_logging_output( - stdout=not args.q, filename=None if args.log == "none" else args.log - ) - elif args.q: - config.set_logging_output(stdout=not args.q, filename="AstroPhot.log") - - if args.dtype is not None: - config.DTYPE = torch.float64 if args.dtype == "float64" else torch.float32 - if args.device is not None: - config.DEVICE = "cpu" if args.device == "cpu" else "cuda:0" - - if args.filename is None: - raise RuntimeError( - "Please pass a config file to astrophot. See 'astrophot --help' for more information, or go to https://astrophot.readthedocs.io" - ) - if args.filename in ["tutorial", "tutorials"]: - tutorials = [ - "https://raw.github.com/Autostronomy/AstroPhot/main/docs/source/tutorials/GettingStarted.ipynb", - "https://raw.github.com/Autostronomy/AstroPhot/main/docs/source/tutorials/GroupModels.ipynb", - "https://raw.github.com/Autostronomy/AstroPhot/main/docs/source/tutorials/ModelZoo.ipynb", - "https://raw.github.com/Autostronomy/AstroPhot/main/docs/source/tutorials/JointModels.ipynb", - "https://raw.github.com/Autostronomy/AstroPhot/main/docs/source/tutorials/FittingMethods.ipynb", - "https://raw.github.com/Autostronomy/AstroPhot/main/docs/source/tutorials/CustomModels.ipynb", - "https://raw.github.com/Autostronomy/AstroPhot/main/docs/source/tutorials/BasicPSFModels.ipynb", - "https://raw.github.com/Autostronomy/AstroPhot/main/docs/source/tutorials/AdvancedPSFModels.ipynb", - "https://raw.github.com/Autostronomy/AstroPhot/main/docs/source/tutorials/ConstrainedModels.ipynb", - ] - for url in tutorials: - try: - R = requests.get(url) - with open(url[url.rfind("/") + 1 :], "w") as f: - f.write(R.text) - except: - print( - f"WARNING: couldn't find tutorial: {url[url.rfind('/')+1:]} check internet connection" - ) - - config.logger.info("collected the tutorials") - else: - raise ValueError(f"Unrecognized request") - - __all__ = ( "models", "image", @@ -170,7 +63,7 @@ def run_from_terminal() -> None: "Module", "config", "backend", - "run_from_terminal", + "ArrayLike", "__version__", "__author__", "__email__", diff --git a/astrophot/fit/hmc.py b/astrophot/fit/hmc.py index f726f8ee..bdb54fb3 100644 --- a/astrophot/fit/hmc.py +++ b/astrophot/fit/hmc.py @@ -52,7 +52,8 @@ def new_configure(self, mass_matrix_shape, adapt_mass_matrix=True, options={}): self.inverse_mass_matrix = inverse_mass_matrix -BlockMassMatrix.configure = new_configure +if pyro is not None: + BlockMassMatrix.configure = new_configure ############################################ diff --git a/astrophot/models/base.py b/astrophot/models/base.py index 04a3b99e..06e166d5 100644 --- a/astrophot/models/base.py +++ b/astrophot/models/base.py @@ -63,7 +63,6 @@ def __init__(self, *, name=None, target=None, window=None, mask=None, filename=N setattr(self, key, param) self.saveattrs.update(self.options) - self.saveattrs.add("window.extent") kwargs.pop("model_type", None) # model_type is set by __new__ if len(kwargs) > 0: diff --git a/astrophot/models/mixins/ferrer.py b/astrophot/models/mixins/ferrer.py index 47cb87f3..ff18208a 100644 --- a/astrophot/models/mixins/ferrer.py +++ b/astrophot/models/mixins/ferrer.py @@ -85,10 +85,10 @@ class iFerrerMixin: _model_type = "ferrer" _parameter_specs = { - "rout": {"units": "arcsec", "valid": (0.0, None), "shape": (), "dynamic": True}, - "alpha": {"units": "unitless", "valid": (0, 10), "shape": (), "dynamic": True}, - "beta": {"units": "unitless", "valid": (0, 2), "shape": (), "dynamic": True}, - "I0": {"units": "flux/arcsec^2", "valid": (0.0, None), "shape": (), "dynamic": True}, + "rout": {"units": "arcsec", "valid": (0.0, None), "dynamic": True}, + "alpha": {"units": "unitless", "valid": (0, 10), "dynamic": True}, + "beta": {"units": "unitless", "valid": (0, 2), "dynamic": True}, + "I0": {"units": "flux/arcsec^2", "valid": (0.0, None), "dynamic": True}, } @torch.no_grad() diff --git a/astrophot/models/model_object.py b/astrophot/models/model_object.py index 8c17a94b..8e6af051 100644 --- a/astrophot/models/model_object.py +++ b/astrophot/models/model_object.py @@ -46,6 +46,7 @@ def __init__(self, *args, psf=None, psf_convolve: bool = False, **kwargs): super().__init__(*args, **kwargs) self.psf = psf self.psf_convolve = psf_convolve + self.saveattrs.add("window.extent") @property def psf(self): diff --git a/docs/source/tutorials/AdvancedPSFModels.ipynb b/docs/source/tutorials/AdvancedPSFModels.ipynb index 287b7f7d..c1cddabd 100644 --- a/docs/source/tutorials/AdvancedPSFModels.ipynb +++ b/docs/source/tutorials/AdvancedPSFModels.ipynb @@ -71,7 +71,7 @@ "source": [ "# Now we initialize on the image\n", "psf_model = ap.Model(\n", - " name=\"init psf\",\n", + " name=\"init_psf\",\n", " model_type=\"moffat psf model\",\n", " target=psf_target,\n", ")\n", @@ -134,7 +134,7 @@ " target=psf_target,\n", ")\n", "psf_group_model = ap.Model(\n", - " name=\"psf group\",\n", + " name=\"psf_group\",\n", " model_type=\"psf group model\",\n", " target=psf_target,\n", " models=[psf_model1, psf_model2],\n", @@ -175,7 +175,7 @@ ")\n", "\n", "true_psf_model = ap.Model(\n", - " name=\"true psf\",\n", + " name=\"true_psf\",\n", " model_type=\"moffat psf model\",\n", " target=psf_target,\n", " n=2,\n", @@ -190,7 +190,7 @@ ")\n", "\n", "true_model = ap.Model(\n", - " name=\"true model\",\n", + " name=\"true_model\",\n", " model_type=\"sersic galaxy model\",\n", " target=target,\n", " center=[50.0, 50.0],\n", @@ -227,7 +227,7 @@ "\n", "# Here we set up a sersic model for the galaxy\n", "plain_galaxy_model = ap.Model(\n", - " name=\"galaxy model\",\n", + " name=\"galaxy_model\",\n", " model_type=\"sersic galaxy model\",\n", " target=target,\n", ")\n", @@ -283,7 +283,7 @@ "\n", "# Here we set up a sersic model for the galaxy\n", "live_galaxy_model = ap.Model(\n", - " name=\"galaxy model\",\n", + " name=\"galaxy_model\",\n", " model_type=\"sersic galaxy model\",\n", " target=target,\n", " psf_convolve=True,\n", diff --git a/docs/source/tutorials/ConstrainedModels.ipynb b/docs/source/tutorials/ConstrainedModels.ipynb index 599df83e..812cb1f6 100644 --- a/docs/source/tutorials/ConstrainedModels.ipynb +++ b/docs/source/tutorials/ConstrainedModels.ipynb @@ -195,7 +195,7 @@ " psf.Rd = allstars[0].psf.Rd\n", " allstars.append(\n", " ap.Model(\n", - " name=f\"star {x} {y}\",\n", + " name=f\"star_{x}_{y}\".replace(\"-\", \"n\"),\n", " model_type=\"point model\",\n", " center=[x, y],\n", " flux=1,\n", @@ -211,7 +211,7 @@ "# A group model holds all the stars together\n", "sky = ap.Model(name=\"sky\", model_type=\"flat sky model\", I=1e-5, target=target)\n", "MODEL = ap.Model(\n", - " name=\"spatial PSF\",\n", + " name=\"spatial_PSF\",\n", " model_type=\"group model\",\n", " models=[sky] + allstars,\n", " target=target,\n", diff --git a/docs/source/tutorials/CustomModels.ipynb b/docs/source/tutorials/CustomModels.ipynb index 9ff0dfd6..154046db 100644 --- a/docs/source/tutorials/CustomModels.ipynb +++ b/docs/source/tutorials/CustomModels.ipynb @@ -131,7 +131,7 @@ "outputs": [], "source": [ "my_model = My_Sersic( # notice we are now using the custom class\n", - " name=\"wow I made a model\",\n", + " name=\"wow_I_made_a_model\",\n", " target=target, # now the model knows what its trying to match\n", " # note we have to give initial values for our new parameters. AstroPhot doesn't know how to auto-initialize them because they are custom\n", " my_n=1.0,\n", @@ -249,7 +249,7 @@ "outputs": [], "source": [ "my_super_model = ap.Model(\n", - " name=\"goodness I made another one\",\n", + " name=\"goodness_I_made_another_one\",\n", " model_type=\"super mysersic galaxy model\", # this is the type we defined above\n", " target=target,\n", ")\n", diff --git a/docs/source/tutorials/FittingMethods.ipynb b/docs/source/tutorials/FittingMethods.ipynb index 7795fa18..797d823d 100644 --- a/docs/source/tutorials/FittingMethods.ipynb +++ b/docs/source/tutorials/FittingMethods.ipynb @@ -108,7 +108,7 @@ " for i, params in enumerate(sersic_params):\n", " model_list.append(\n", " ap.Model(\n", - " name=f\"sersic {i}\",\n", + " name=f\"sersic_{i}\",\n", " model_type=\"sersic galaxy model\",\n", " target=target,\n", " center=[params[0], params[1]],\n", diff --git a/docs/source/tutorials/GettingStarted.ipynb b/docs/source/tutorials/GettingStarted.ipynb index c1e680ac..00c6de63 100644 --- a/docs/source/tutorials/GettingStarted.ipynb +++ b/docs/source/tutorials/GettingStarted.ipynb @@ -123,7 +123,7 @@ "source": [ "# This model now has a target that it will attempt to match\n", "model2 = ap.Model(\n", - " name=\"model with target\",\n", + " name=\"model_with_target\",\n", " model_type=\"sersic galaxy model\",\n", " target=target,\n", ")\n", @@ -330,7 +330,7 @@ "# here we make a sersic model that can only have q and n in a narrow range\n", "# Also, we give PA and initial value and lock that so it does not change during fitting\n", "constrained_param_model = ap.Model(\n", - " name=\"constrained parameters\",\n", + " name=\"constrained_parameters\",\n", " model_type=\"sersic galaxy model\",\n", " q={\"valid\": (0.4, 0.6)},\n", " n={\"valid\": (2, 3)},\n", diff --git a/docs/source/tutorials/GettingStartedJAX.ipynb b/docs/source/tutorials/GettingStartedJAX.ipynb index 717cabcd..f7f1c769 100644 --- a/docs/source/tutorials/GettingStartedJAX.ipynb +++ b/docs/source/tutorials/GettingStartedJAX.ipynb @@ -144,7 +144,7 @@ "source": [ "# This model now has a target that it will attempt to match\n", "model2 = ap.Model(\n", - " name=\"model with target\",\n", + " name=\"model_with_target\",\n", " model_type=\"sersic galaxy model\",\n", " target=target,\n", ")\n", @@ -351,7 +351,7 @@ "# here we make a sersic model that can only have q and n in a narrow range\n", "# Also, we give PA and initial value and lock that so it does not change during fitting\n", "constrained_param_model = ap.Model(\n", - " name=\"constrained parameters\",\n", + " name=\"constrained_parameters\",\n", " model_type=\"sersic galaxy model\",\n", " q={\"valid\": (0.4, 0.6)},\n", " n={\"valid\": (2, 3)},\n", diff --git a/docs/source/tutorials/GroupModels.ipynb b/docs/source/tutorials/GroupModels.ipynb index d43feb28..fb92ada5 100644 --- a/docs/source/tutorials/GroupModels.ipynb +++ b/docs/source/tutorials/GroupModels.ipynb @@ -121,7 +121,7 @@ "for win in windows:\n", " seg_models.append(\n", " ap.Model(\n", - " name=f\"object {win:02d}\",\n", + " name=f\"object_{win:02d}\",\n", " window=windows[win],\n", " model_type=\"sersic galaxy model\",\n", " target=target,\n", @@ -131,7 +131,7 @@ " )\n", " )\n", "sky = ap.Model(\n", - " name=f\"sky level\",\n", + " name=f\"sky_level\",\n", " model_type=\"flat sky model\",\n", " target=target,\n", " I={\"valid\": (0, None)},\n", diff --git a/docs/source/tutorials/ImageAlignment.ipynb b/docs/source/tutorials/ImageAlignment.ipynb index 84aa9f12..0f8c58ff 100644 --- a/docs/source/tutorials/ImageAlignment.ipynb +++ b/docs/source/tutorials/ImageAlignment.ipynb @@ -75,17 +75,17 @@ "# fmt: off\n", "# r-band model\n", "psfr = ap.Model(name=\"psfr\", model_type=\"moffat psf model\", n=2, Rd=1.0, target=target_r.psf_image(data=np.zeros((51, 51))))\n", - "star1r = ap.Model(name=\"star1-r\", model_type=\"point model\", window=[0, 60, 80, 135], center=[12, 9], psf=psfr, target=target_r)\n", - "star2r = ap.Model(name=\"star2-r\", model_type=\"point model\", window=[40, 90, 20, 70], center=[3, -7], psf=psfr, target=target_r)\n", - "star3r = ap.Model(name=\"star3-r\", model_type=\"point model\", window=[109, 150, 40, 90], center=[-15, -3], psf=psfr, target=target_r)\n", - "modelr = ap.Model(name=\"model-r\", model_type=\"group model\", models=[star1r, star2r, star3r], target=target_r)\n", + "star1r = ap.Model(name=\"star1_r\", model_type=\"point model\", window=[0, 60, 80, 135], center=[12, 9], psf=psfr, target=target_r)\n", + "star2r = ap.Model(name=\"star2_r\", model_type=\"point model\", window=[40, 90, 20, 70], center=[3, -7], psf=psfr, target=target_r)\n", + "star3r = ap.Model(name=\"star3_r\", model_type=\"point model\", window=[109, 150, 40, 90], center=[-15, -3], psf=psfr, target=target_r)\n", + "modelr = ap.Model(name=\"model_r\", model_type=\"group model\", models=[star1r, star2r, star3r], target=target_r)\n", "\n", "# g-band model\n", "psfg = ap.Model(name=\"psfg\", model_type=\"moffat psf model\", n=2, Rd=1.0, target=target_g.psf_image(data=np.zeros((51, 51))))\n", - "star1g = ap.Model(name=\"star1-g\", model_type=\"point model\", window=[0, 60, 80, 135], center=star1r.center, psf=psfg, target=target_g)\n", - "star2g = ap.Model(name=\"star2-g\", model_type=\"point model\", window=[40, 90, 20, 70], center=star2r.center, psf=psfg, target=target_g)\n", - "star3g = ap.Model(name=\"star3-g\", model_type=\"point model\", window=[109, 150, 40, 90], center=star3r.center, psf=psfg, target=target_g)\n", - "modelg = ap.Model(name=\"model-g\", model_type=\"group model\", models=[star1g, star2g, star3g], target=target_g)\n", + "star1g = ap.Model(name=\"star1_g\", model_type=\"point model\", window=[0, 60, 80, 135], center=star1r.center, psf=psfg, target=target_g)\n", + "star2g = ap.Model(name=\"star2_g\", model_type=\"point model\", window=[40, 90, 20, 70], center=star2r.center, psf=psfg, target=target_g)\n", + "star3g = ap.Model(name=\"star3_g\", model_type=\"point model\", window=[109, 150, 40, 90], center=star3r.center, psf=psfg, target=target_g)\n", + "modelg = ap.Model(name=\"model_g\", model_type=\"group model\", models=[star1g, star2g, star3g], target=target_g)\n", "\n", "# total model\n", "target_full = ap.TargetImageList([target_r, target_g])\n", diff --git a/docs/source/tutorials/JointModels.ipynb b/docs/source/tutorials/JointModels.ipynb index 8b1eee03..e211be9d 100644 --- a/docs/source/tutorials/JointModels.ipynb +++ b/docs/source/tutorials/JointModels.ipynb @@ -101,14 +101,14 @@ "# group models designed for each band individually, but that would be unnecessarily complex for a tutorial\n", "\n", "model_r = ap.Model(\n", - " name=\"rband model\",\n", + " name=\"rband_model\",\n", " model_type=\"sersic galaxy model\",\n", " target=target_r,\n", " psf_convolve=True,\n", ")\n", "\n", "model_W1 = ap.Model(\n", - " name=\"W1band model\",\n", + " name=\"W1band_model\",\n", " model_type=\"sersic galaxy model\",\n", " target=target_W1,\n", " center=[0, 0],\n", @@ -117,7 +117,7 @@ ")\n", "\n", "model_NUV = ap.Model(\n", - " name=\"NUVband model\",\n", + " name=\"NUVband_model\",\n", " model_type=\"sersic galaxy model\",\n", " target=target_NUV,\n", " center=[0, 0],\n", @@ -143,7 +143,7 @@ "# We can now make the joint model object\n", "\n", "model_full = ap.Model(\n", - " name=\"LEDA 41136\",\n", + " name=\"LEDA41136\",\n", " model_type=\"group model\",\n", " models=[model_r, model_W1, model_NUV],\n", " target=target_full,\n", @@ -304,7 +304,7 @@ " sub_list = []\n", " sub_list.append(\n", " ap.Model(\n", - " name=f\"rband model {i}\",\n", + " name=f\"rband_model_{i}\",\n", " model_type=\"sersic galaxy model\", # we could use spline models for the r-band since it is well resolved\n", " target=target_r,\n", " window=rwindows[window],\n", @@ -316,7 +316,7 @@ " )\n", " sub_list.append(\n", " ap.Model(\n", - " name=f\"W1band model {i}\",\n", + " name=f\"W1band_model_{i}\",\n", " model_type=\"sersic galaxy model\",\n", " target=target_W1,\n", " window=w1windows[window],\n", @@ -325,7 +325,7 @@ " )\n", " sub_list.append(\n", " ap.Model(\n", - " name=f\"NUVband model {i}\",\n", + " name=f\"NUVband_model_{i}\",\n", " model_type=\"sersic galaxy model\",\n", " target=target_NUV,\n", " window=nuvwindows[window],\n", @@ -341,7 +341,7 @@ " # Make the multiband model for this object\n", " model_list.append(\n", " ap.Model(\n", - " name=f\"model {i}\",\n", + " name=f\"model_{i}\",\n", " model_type=\"group model\",\n", " target=target_full,\n", " models=sub_list,\n", @@ -349,7 +349,7 @@ " )\n", "# Make the full model for this system of objects\n", "MODEL = ap.Model(\n", - " name=f\"full model\",\n", + " name=f\"full_model\",\n", " model_type=\"group model\",\n", " target=target_full,\n", " models=model_list,\n", diff --git a/pyproject.toml b/pyproject.toml index faaf81cf..a998410e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,6 @@ build-backend = "hatchling.build" [project] name = "astrophot" dynamic = [ - "dependencies", "version" ] authors = [ @@ -13,7 +12,7 @@ authors = [ ] description = "A fast, flexible, automated, and differentiable astronomical image 2D forward modelling tool for precise parallel multi-wavelength photometry." readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.10" license = {file = "LICENSE"} keywords = [ "astrophot", @@ -25,12 +24,22 @@ keywords = [ "pytorch" ] classifiers=[ - "Development Status :: 1 - Planning", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Science/Research", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ] +dependencies=[ + "astropy>=5.3", + "caskade~=0.15.0", + "h5py>=3.8.0", + "matplotlib>=3.7", + "numpy>=1.24.0,<2.0.0", + "scipy>=1.10.0", + "torch>=2.0.0", + "tqdm>=4.65.0", +] [project.urls] Homepage = "https://autostronomy.github.io/AstroPhot/" @@ -39,13 +48,23 @@ Repository = "https://github.com/Autostronomy/AstroPhot" Issues = "https://github.com/Autostronomy/AstroPhot/issues" [project.optional-dependencies] -dev = ["pre-commit", "nbval", "nbconvert", "graphviz", "ipywidgets", "jupyter-book", "matplotlib", "photutils", "scikit-image", "caustics", "emcee", "corner", "jax<=0.7.0", "pyvo"] - -[project.scripts] -astrophot = "astrophot:run_from_terminal" - -[tool.hatch.metadata.hooks.requirements_txt] -files = ["requirements.txt"] +dev = [ + "pre-commit", + "nbval", + "nbconvert", + "graphviz", + "ipywidgets", + "jupyter-book<2.0", + "matplotlib", + "photutils", + "scikit-image", + "caustics", + "pyro-ppl>=1.8.0", + "emcee", + "corner", + "jax<=0.7.0", + "pyvo" +] [tool.hatch.version] source = "vcs" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 1a4dfb24..00000000 --- a/requirements.txt +++ /dev/null @@ -1,11 +0,0 @@ -astropy>=5.3 -caskade>=0.6.0 -h5py>=3.8.0 -matplotlib>=3.7 -numpy>=1.24.0,<2.0.0 -pyro-ppl>=1.8.0 -pyyaml>=6.0 -requests>=2.30.0 -scipy>=1.10.0 -torch>=2.0.0 -tqdm>=4.65.0 diff --git a/tests/conftest.py b/tests/conftest.py index 92081514..6690744f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,8 @@ import matplotlib import matplotlib.pyplot as plt import pytest +import numpy as np +import astrophot as ap @pytest.fixture(autouse=True) @@ -13,3 +15,47 @@ def close_show(*args, **kwargs): # Also ensure we are in a non-GUI backend matplotlib.use("Agg") + + +@pytest.fixture() +def sersic(request): + + np.random.seed(request.param.get("seed", 12345)) + shape = request.param.get("shape", (52, 50)) + mask = request.param.get("mask", None) + if mask is None: + mask = np.zeros(shape, dtype=bool) + mask[0][0] = True + target = request.param.get("target", None) + pixelscale = 0.8 + if target is None: + target = ap.TargetImage( + data=np.zeros(shape), + pixelscale=pixelscale, + psf=ap.utils.initialize.gaussian_psf(2 / pixelscale, 11, pixelscale), + mask=mask, + zeropoint=21.5, + ) + + MODEL = ap.models.SersicGalaxy( + name="basic_sersic_model", + target=target, + center=request.param.get("center", [20.5, 21.4]), + PA=request.param.get("PA", 45 * np.pi / 180), + q=request.param.get("q", 0.7), + n=request.param.get("n", 1.5), + Re=request.param.get("Re", 15.1), + Ie=request.param.get("Ie", 10.0), + sampling_mode="quad:5", + ) + + if request.param.get("target", None) is None: + img = ap.backend.to_numpy(MODEL().data) + target.data = ( + img + + np.random.normal(scale=0.5, size=img.shape) + + np.random.normal(scale=np.sqrt(img) / 10) + ) + target.variance = 0.5**2 + img / 100 + + return MODEL diff --git a/tests/test_cmos_image.py b/tests/test_cmos_image.py index 4cfb5123..16e6555d 100644 --- a/tests/test_cmos_image.py +++ b/tests/test_cmos_image.py @@ -44,7 +44,7 @@ def test_cmos_image_creation(cmos_target): def test_cmos_model_sample(cmos_target): model = ap.Model( - name="test cmos", + name="test_cmos", model_type="sersic galaxy model", target=cmos_target, center=(3, 5), diff --git a/tests/test_fit.py b/tests/test_fit.py index bfb2ad13..1a53449e 100644 --- a/tests/test_fit.py +++ b/tests/test_fit.py @@ -18,7 +18,7 @@ def test_chunk_jacobian(center, PA, q, n, Re): target = make_basic_sersic() model = ap.Model( - name="test sersic", + name="test_sersic", model_type="sersic galaxy model", center=center, PA=PA, @@ -53,7 +53,7 @@ def test_chunk_jacobian(center, PA, q, n, Re): def sersic_model(): target = make_basic_sersic() model = ap.Model( - name="test sersic", + name="test_sersic", model_type="sersic galaxy model", center=[20, 20], PA=np.pi, @@ -135,7 +135,7 @@ def test_fitters_iter(): target=target, ) model = ap.Model( - name="test group", + name="test_group", model_type="group model", models=[model1, model2], target=target, diff --git a/tests/test_group_models.py b/tests/test_group_models.py index 9285c0ac..bc0d2949 100644 --- a/tests/test_group_models.py +++ b/tests/test_group_models.py @@ -25,16 +25,16 @@ def test_jointmodel_creation(): tar = ap.TargetImageList([tar1, tar2]) mod1 = ap.models.FlatSky( - name="base model 1", + name="base_model_1", target=tar1, ) mod2 = ap.models.FlatSky( - name="base model 2", + name="base_model_2", target=tar2, ) smod = ap.Model( - name="group model", + name="group_model", model_type="group model", models=[mod1, mod2], target=tar, @@ -54,19 +54,19 @@ def test_psfgroupmodel_creation(): tar = make_basic_gaussian_psf() mod1 = ap.Model( - name="base model 1", + name="base_model_1", model_type="moffat psf model", target=tar, ) mod2 = ap.Model( - name="base model 2", + name="base_model_2", model_type="moffat psf model", target=tar, ) smod = ap.Model( - name="group model", + name="group_model", model_type="psf group model", models=[mod1, mod2], target=tar, @@ -104,7 +104,7 @@ def test_joint_multi_band_multi_object(): model52 = ap.Model(name="model52", model_type="sersic galaxy model", window=(0, 49, 0, 60), target=target3) model5 = ap.Model(name="model5", model_type="group model", models=[model51, model52], target=ap.TargetImageList([target2, target3])) - model = ap.Model(name="joint model", model_type="group model", models=[model1, model2, model3, model4, model5], target=ap.TargetImageList([target1, target2, target3, target4])) + model = ap.Model(name="joint_model", model_type="group model", models=[model1, model2, model3, model4, model5], target=ap.TargetImageList([target1, target2, target3, target4])) # fmt: on model.initialize() diff --git a/tests/test_model.py b/tests/test_model.py index a349e137..ac9dd4d1 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -13,7 +13,7 @@ def test_model_sampling_modes(): target = make_basic_sersic(90, 100) model = ap.Model( - name="test sersic", + name="test_sersic", model_type="sersic galaxy model", center=[40, 41.9], PA=60 * np.pi / 180, @@ -97,7 +97,7 @@ def test_model_errors(): with pytest.raises(ap.errors.InvalidTarget): ap.Model( - name="test model", + name="test_model", model_type="sersic galaxy model", target=target, ) @@ -106,7 +106,7 @@ def test_model_errors(): target = make_basic_sersic() with pytest.raises(ap.errors.UnrecognizedModel): ap.Model( - name="test model", + name="test_model", model_type="sersic gaaxy model", target=target, ) @@ -131,7 +131,7 @@ def test_all_model_sample(model_type): target = make_basic_sersic() target.zeropoint = 22.5 MODEL = ap.Model( - name="test model", + name="test_model", model_type=model_type, target=target, integrate_mode=( @@ -202,7 +202,7 @@ def test_sersic_save_load(): target = make_basic_sersic() model = ap.Model( - name="test sersic", + name="test_sersic", model_type="sersic galaxy model", center=[20, 20], PA=60 * np.pi / 180, @@ -244,7 +244,7 @@ def test_sersic_save_load(): def test_chunk_sample(center, PA, q, n, Re): target = make_basic_sersic() model = ap.Model( - name="test sersic", + name="test_sersic", model_type="sersic galaxy model", center=center, PA=PA, diff --git a/tests/test_param.py b/tests/test_param.py index 7740dc1b..d3bd4156 100644 --- a/tests/test_param.py +++ b/tests/test_param.py @@ -35,8 +35,8 @@ def test_param(): def test_module(): target = make_basic_sersic() - model1 = ap.Model(name="test model 1", model_type="sersic galaxy model", target=target) - model2 = ap.Model(name="test model 2", model_type="sersic galaxy model", target=target) + model1 = ap.Model(name="test_model_1", model_type="sersic galaxy model", target=target) + model2 = ap.Model(name="test_model_2", model_type="sersic galaxy model", target=target) model = ap.Model(name="test", model_type="group model", target=target, models=[model1, model2]) model.initialize() diff --git a/tests/test_plots.py b/tests/test_plots.py index 4d6a59c7..35d8f2e8 100644 --- a/tests/test_plots.py +++ b/tests/test_plots.py @@ -46,7 +46,7 @@ def test_target_image_list(): def test_model_image(): target = make_basic_sersic() new_model = ap.Model( - name="constrained sersic", + name="constrained_sersic", model_type="sersic galaxy model", center=[20, 20], PA=60 * np.pi / 180, @@ -68,7 +68,7 @@ def test_model_image(): def test_residual_image(): target = make_basic_sersic() new_model = ap.Model( - name="constrained sersic", + name="constrained_sersic", model_type="sersic galaxy model", center=[20, 20], PA=60 * np.pi / 180, @@ -90,7 +90,7 @@ def test_residual_image(): def test_model_windows(): target = make_basic_sersic() new_model = ap.Model( - name="constrained sersic", + name="constrained_sersic", model_type="sersic galaxy model", center=[20, 20], PA=60 * np.pi / 180, @@ -124,7 +124,7 @@ def test_covariance_matrix(): def test_radial_profile(): target = make_basic_sersic() new_model = ap.Model( - name="constrained sersic", + name="constrained_sersic", model_type="sersic galaxy model", center=[20, 20], PA=60 * np.pi / 180, @@ -146,7 +146,7 @@ def test_radial_profile(): def test_radial_median_profile(): target = make_basic_sersic() new_model = ap.Model( - name="constrained sersic", + name="constrained_sersic", model_type="sersic galaxy model", center=[20, 20], PA=60 * np.pi / 180, diff --git a/tests/test_psfmodel.py b/tests/test_psfmodel.py index 586672ed..9c6c7ca3 100644 --- a/tests/test_psfmodel.py +++ b/tests/test_psfmodel.py @@ -26,7 +26,7 @@ def test_all_psfmodel_sample(model_type): kwargs = {} target = make_basic_gaussian_psf(pixelscale=0.8) MODEL = ap.Model( - name="test model", + name="test_model", model_type=model_type, target=target, normalize_psf=False, diff --git a/tests/utils.py b/tests/utils.py index 7bbbb9df..038bb747 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -53,7 +53,7 @@ def make_basic_sersic( ) MODEL = ap.models.SersicGalaxy( - name="basic sersic model", + name="basic_sersic_model", target=target, center=[x, y], PA=PA, @@ -95,7 +95,7 @@ def make_basic_gaussian( ) MODEL = ap.models.GaussianGalaxy( - name="basic gaussian source", + name="basic_gaussian_source", target=target, center=[x, y], sigma=sigma,